2011-09-09 14 views
12

Prima di tutto, ecco la mia messa a punto corrente:SyncDB di Django fallisce con MySQL errno: 150

Django: la versione 1.3

MySQL: la versione 4.0.18 (non la mia prima scelta ...)

quando eseguo syncdb, ottengo il seguente errore:

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)") 

da quello che ho capito che ha qualcosa a che fare con il modo in InnoDB gestisce chiavi esterne. Ecco ciò che il mio file di impostazione appare come:

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

Quando "SET TABLE_TYPE = InnoDB" non è specfied, tutto fila liscio. Mi sono guardato intorno in rete e sembra che il motore InnoDB non gradisca qualcosa su the SQL Django is generating

Per ora, l'unico lavoro che ho trovato è stato creare le tabelle da solo e utilizzare inspectDB per generare i modelli. ..

C'è una soluzione per questo? Grazie!

risposta

0

Ho rintracciato la fonte del problema. Quando si creano 2 tabelle InnoDB con una relazione di chiave esterna, la colonna chiave esterna deve essere indicizzata in modo esplicito prior to MySQL 4.1.2. Usando l'ORM di Django, questo può essere fatto usando l'opzione db_index=True nel campo chiave esterna. Tuttavia, nell'SQL generato da Django, l'istruzione CREATE INDEX viene emessa dopo la creazione della relazione di chiave esterna. Ad esempio, per i seguenti modelli:

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 il seguente codice 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; 

Se si prova l'esecuzione di questo codice utilizzando MySQL 4.0, un errno 150 si verifica quando si cerca di eseguire il ALTER TABLE dichiarazione. Ma se l'istruzione CREATE INDEX viene emessa per prima, tutto funziona come un incantesimo. Per quanto posso dire, l'unica soluzione per questo è creare manualmente la propria tabella e utilizzare successivamente inspectdb per generare i modelli.

Inoltre, ho creato un nuovo Django ticket.

+0

Per creare manualmente le tabelle con il minimo sforzo, copia e modifica l'output di ['django-admin.py sql'] (https://docs.djangoproject.com/en/dev/ref/django-admin/#sql- comando appname-appname) o utilizzare il comando ['django-admin.py customsql'] (https://docs.djangoproject.com/en/dev/ref/django-admin/#sqlcustom-appname-appname). –

4

MySQL docs dire questo:

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.

Inserisci il codice del modello qui per farci vedere che cosa può essere sbagliato. Se non puoi, e non sai cosa c'è di sbagliato, prova a dividere in due le revisioni del repository, o bisecare l'applicazione: disattiva la metà delle applicazioni, verifica se si sincronizza correttamente, quindi dividi la parte che contiene il modello errato e così via.

+0

Grazie per la risposta culebrón! Tuttavia, i miei modelli non stanno causando il problema qui. Come puoi vedere nello stack trace, syncdb fallisce durante la creazione delle tabelle auth di Django. Lo script fallisce, anche con il modello più semplice. – RedsChineseFood

3

Recentemente ho ricevuto anche questo errore. Nel mio caso, questo errore si è verificato perché la tabella che contiene la chiave esterna sta utilizzando un motore diverso confrontandolo con la tabella che si intende creare. un modo pigro per risolvere questo problema è di unificare motore di queste due tabelle con:

ALTER TABLE table_name ENGINE = engine_type; 

E ha funzionato per me.

+0

Grazie per aver funzionato su MySQL 5 – leech

15

utilizzando Django 1.5, l'errore era che mysql creava tabelle con Innodb come motore predefinito.La soluzione era di aggiungere quanto segue alle impostazioni per il database e questo ha creato problemi con i vincoli:

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

} 
Problemi correlati