Подтвердить что ты не робот

Ошибка Django syncdb с MySQL errno: 150

Во-первых, здесь моя текущая настройка:

Django: версия 1.3

MySQL: версия 4.0.18 (не мой первый выбор...)

Когда я запускаю syncdb, я получаю следующую ошибку:

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

Из того, что я понимаю, это имеет какое-то отношение к тому, как InnoDB обрабатывает внешние ключи. Вот как выглядит мой файл настроек:

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

Если "SET table_type = INNODB" не задано, все выполняется гладко. Я огляделся по сети, и кажется, что движок InnoDB не любит что-то о генерирует SQL Django

В настоящее время единственная работа, которую я обнаружил, заключалась в том, чтобы создать таблицы самостоятельно и использовать inspectDB для генерации моделей...

Есть ли исправление для этого? Спасибо!

4b9b3361

Ответ 1

Я проследил источник проблемы. При создании 2 таблиц InnoDB с отношением внешнего ключа столбец внешнего ключа должен быть явно индексирован до MySQL 4.1.2. Используя Django ORM, это можно сделать, используя опцию db_index=True в поле внешнего ключа. Однако в Django сгенерированном SQL оператор CREATE INDEX выдается после создания отношения внешнего ключа. Например, для следующих моделей:

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 генерирует следующий код 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;  

Если вы попытаетесь запустить этот код с использованием MySQL 4.0, при попытке выполнить инструкцию ALTER TABLE произойдет ошибка errno 150. Но если утверждение CREATE INDEX выдается первым, все работает как шарм. Насколько я могу судить, единственным обходным решением для этого является создание собственной таблицы вручную и последующее использование inspectdb для генерации моделей.

Кроме того, я создал новый Django.

Ответ 2

используя Django 1.5, ошибка заключалась в том, что mysql создает таблицы с Innodb как двигатель по умолчанию. Решение заключалось в том, чтобы добавить следующие параметры в базу данных, и это создало проблемы с ограничениями:

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

}

Ответ 3

MySQL docs говорят об этом:

Невозможно создать таблицу. Если сообщение об ошибке относится к ошибке 150, таблица создание завершилось неудачно, потому что ограничение внешнего ключа было неправильным формируется. Если сообщение об ошибке относится к ошибке -1, создание таблицы вероятно, не удалось, потому что таблица содержит имя столбца, которое соответствует имя внутренней таблицы InnoDB.

Отправьте свой код модели, чтобы мы могли видеть, что может быть неправильным. Если вы не можете и не знаете, что неправильно, попробуйте деактивировать ревизии репозитория или деактивировать приложение: отключите половину приложений, посмотрите, правильно ли они синхронизируются, затем разделите часть, содержащую плохую модель, и так далее.

Ответ 4

Недавно я тоже получил эту ошибку. В моем случае эта ошибка возникла из-за того, что таблица, содержащая внешний ключ, использует другой движок по сравнению с таблицей, которую вы собираетесь создавать. ленивый способ решить эту проблему - объединить движок этих двух таблиц с помощью:

ALTER TABLE table_name ENGINE = engine_type;

И это сработало для меня.