2011-09-09 16 views
12

Po pierwsze, oto moja obecna konfiguracja:syncdb Django nie działa z MySQL errno: 150

Django: wersja 1.3

MySQL wersja 4.0.18 (nie mój 1st choice ...)

kiedy uruchomić syncdb, pojawia się następujący błąd:

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

z tego co rozumiem, to ma coś wspólnego z tym, jak InnoDB obsługuje klucze obce. Oto co mój plik ustawienie wygląda następująco:

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

Kiedy "SET TABLE_TYPE = InnoDB" nie jest specfied, wszystko działa płynnie. Rozglądałem się po sieci i wygląda na to, że silnik InnoDB nie lubi czegoś o the SQL Django is generating Na razie jedyną pracą, jaką znalazłem, było stworzenie tabel samodzielnie i użycie inspectDB do wygenerowania modeli. ..

Czy jest na to poprawka? Dzięki!

Odpowiedz

0

Prześledziłem źródło problemu. Podczas tworzenia 2 tabel InnoDB z relacją klucza obcego kolumna klucza obcego musi być jawnie zaindeksowana prior to MySQL 4.1.2. Korzystając z ORM Django, można to zrobić za pomocą opcji db_index=True w polu klucza obcego. Jednak w wygenerowanym przez Django języku SQL instrukcja CREATE INDEX jest wydawana po utworzeniu relacji klucza obcego. Na przykład, dla następujących modeli:

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 generuje następujący kod 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; 

Jeśli spróbować uruchomić ten kod przy użyciu MySQL 4.0, to errno 150 nastąpi podczas próby wykonania ALTER TABLE komunikat. Ale jeśli najpierw zostanie wydane oświadczenie CREATE INDEX, wszystko działa jak czar. O ile mogę powiedzieć, jedynym rozwiązaniem tego problemu jest ręczne utworzenie własnej tabeli i późniejsze wygenerowanie modeli za pomocą inspectdb.

Ponadto utworzyłem nowy Django ticket.

+0

Aby ręcznie tworzyć tabele przy minimalnym nakładzie pracy, skopiuj i edytuj dane wyjściowe programu ['django-admin.py sql'] (https://docs.djangoproject.com/en/dev/ref/django-admin/#sql- appname-appname) lub użyj polecenia ['django-admin.py customql'] (https://docs.djangoproject.com/en/dev/ref/django-admin/#sqlcustom-appname-appname). –

4

MySQL docs powiedzieć:

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.

postu kod modelu, żeby zobaczmy co może być nie tak. Jeśli nie możesz i nie wiesz, co jest nie tak, spróbuj przeciąć wersje repozytorium lub podzielić aplikację na dwie części: wyłącz połowę aplikacji, sprawdź, czy synchronizuje się poprawnie, a następnie podziel na dwie części, które zawierają zły model i tak dalej.

+0

Dzięki za odpowiedź culebrón! Jednak moje modele nie powodują problemu. Jak widać na wykresie stosu, syncdb kończy się niepowodzeniem podczas tworzenia tabel autoryzacji django. Skrypt nie działa, nawet w przypadku najbardziej podstawowego modelu. – RedsChineseFood

3

Niedawno dostałem ten błąd. W moim przypadku błąd ten wystąpił, ponieważ tabela zawierająca klucz obcy korzysta z innego silnika porównywalnego z tabelą, którą zamierzasz utworzyć. leniwy sposób na rozwiązanie tego problemu jest ujednolicenie silnik tych dwóch tabel za pomocą:

ALTER TABLE table_name ENGINE = engine_type; 

I pracował dla mnie.

+0

Dzięki temu zadziałało dla mnie na MySQL 5 – leech

15

przy użyciu Django 1.5, błąd polegał na tym, że mysql tworzy tabele z Innodb jako domyślnym silnikiem.Rozwiązanie polegało na dodaniu następujących ustawień do ustawień bazy danych i spowodowało powstanie problemów z ograniczeniami:

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

} 
Powiązane problemy