2011-09-09 13 views
12

En primer lugar, aquí está mi configuración actual:syncdb de Django falla con MySQL Error: 150

Django: la versión 1.3

MySQL: Versión 4.0.18 (no es mi primera opción ...)

cuando corro syncdb, me sale el siguiente error:

Creating tables ... 
Creating table auth_permission 
Creating table auth_group_permissions 
Traceback (most recent call last): 
    File "C:\path_to_app\manage.py", line 14, in <module> 
    execute_manager(settings) 
    File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line 438, in execute_manager 
    utility.execute() 
    File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line 379, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "C:\Python27\lib\site-packages\django\core\management\base.py", line 191, in run_from_argv 
    self.execute(*args, **options.__dict__) 
    File "C:\Python27\lib\site-packages\django\core\management\base.py", line 220, in execute 
    output = self.handle(*args, **options) 
    File "C:\Python27\lib\site-packages\django\core\management\base.py", line 351, in handle 
    return self.handle_noargs(**options) 
    File "C:\Python27\lib\site-packages\django\core\management\commands\syncdb.py", line 101, in handle_noargs 
    cursor.execute(statement) 
    File "C:\Python27\lib\site-packages\django\db\backends\util.py", line 34, in execute 
    return self.cursor.execute(sql, params) 
    File "C:\Python27\lib\site-packages\django\db\backends\mysql\base.py", line 86, in execute 
    return self.cursor.execute(query, args) 
    File "C:\Python27\lib\site-packages\MySQLdb\cursors.py", line 174, in execute 
    self.errorhandler(self, exc, value) 
    File "C:\Python27\lib\site-packages\MySQLdb\connections.py", line 36, in defaulterrorhandler 
    raise errorclass, errorvalue 
_mysql_exceptions.OperationalError: (1005, "Can't create table '.\\database_name\\#sql-d64_e75f2.frm' (errno: 150)") 

por lo que entiendo que tiene algo que ver con la forma en InnoDB maneja las claves externas. Esto es lo que se ve mi archivo de configuración como:

DATABASES = { 
    'default': { 
     .... 
     'OPTIONS': { 'init_command': 'SET table_type=INNODB;', 'charset': 'latin1'}, 
    }, 
} 

Cuando no se specfied "SET table_type = INNODB", todo funciona sin problemas. He buscado en la red y parece que el motor InnoDB no le gusta algo sobre the SQL Django is generating

Por ahora, el único trabajo que encontré fue crear las tablas yo mismo, y usar inspectDB para generar los modelos. ..

¿Hay una solución para esto? ¡Gracias!

Respuesta

0

He rastreado el origen del problema. Al crear 2 tablas InnoDB con una relación de clave externa, la columna de clave externa debe indexarse ​​explícitamente prior to MySQL 4.1.2. Usando el ORM de Django, esto se puede hacer usando la opción db_index=True en el campo de la clave externa. Sin embargo, en el SQL generado de Django, la instrucción CREATE INDEX se emite después de que se crea la relación de clave externa. Por ejemplo, para los siguientes modelos:

class Customer(models.Model): 
    first_name = models.CharField(max_length=100) 
    last_name = models.CharField(max_length=100) 

class Order(models.Model): 
    customer = models.ForeignKey(Customer, db_index=True) 

Django genera el siguiente código SQL:

BEGIN; 
CREATE TABLE `foo_app_customer` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, 
    `first_name` varchar(100) NOT NULL, 
    `last_name` varchar(100) NOT NULL 
) 
; 
CREATE TABLE `foo_app_order` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, 
    `customer_id` integer NOT NULL 
) 
; 
ALTER TABLE `foo_app_order` ADD CONSTRAINT `customer_id_refs_id_27e4f922` FOREIGN KEY (`customer_id`) REFERENCES `foo_app_customer` (`id`); 
CREATE INDEX `foo_app_order_12366e04` ON `foo_app_order` (`customer_id`); 
COMMIT; 

Si intenta ejecutar este código usando MySQL 4.0, un error 150 que ocurrirá cuando se trata de ejecutar la ALTER TABLE declaración. Pero si la declaración CREATE INDEX se emite primero, todo funciona como un amuleto. Por lo que puedo decir, la única solución para esto es crear su propia tabla manualmente y usar inspectdb después para generar los modelos.

Además, he creado un nuevo Django ticket.

+0

Para crear sus tablas manualmente con un mínimo esfuerzo, copie y edite el resultado de ['django-admin.py sql'] (https://docs.djangoproject.com/en/dev/ref/django-admin/#sql- appname-appname) o use el comando ['django-admin.py customsql'] (https://docs.djangoproject.com/en/dev/ref/django-admin/#sqlcustom-appname-appname). –

4

MySQL docs decir esto:

Cannot create table. If the error message refers to error 150, table creation failed because a foreign key constraint was not correctly formed. If the error message refers to error –1, table creation probably failed because the table includes a column name that matched the name of an internal InnoDB table.

Publica tu código del modelo aquí para hacernos ver lo que puede estar equivocado. Si no puede, y no sabe lo que está mal, intente dividir las revisiones del repositorio o bisecte la aplicación: apague la mitad de las aplicaciones, vea si se sincroniza correctamente, luego biseque la parte que contiene el modelo incorrecto, y así sucesivamente.

+0

Gracias por la respuesta culebrón! Sin embargo, mis modelos no están causando el problema aquí. Como puede ver en el seguimiento de pila, syncdb falla al crear las tablas autjan de django. La secuencia de comandos falla, incluso con el modelo más básico. – RedsChineseFood

3

Recientemente recibí este error, también. En mi caso, este error se produjo porque la tabla que contiene la clave externa usa un motor diferente que compara con la tabla que va a crear. una forma perezosa para resolver este problema es unificar motor de estas dos tablas usando:

ALTER TABLE table_name ENGINE = engine_type; 

Y funcionó para mí.

+0

Gracias esto funcionó para mí en MySQL 5 – leech

15

usando Django 1.5, el error fue que mysql creaba tablas con Innodb como motor predeterminado.La solución fue agregar lo siguiente a la configuración de la base de datos y esto creó problemas con restricciones:

DATABASES = { 
'default': { 
    'ENGINE': 'django.db.backends.mysql', 
    'NAME': 'etc....', 
    'OPTIONS': { 
      "init_command": "SET storage_engine=MyISAM", 
    }, 
}, 

} 
Cuestiones relacionadas