Syncdb Django не работает с MySQL errno: 150 - PullRequest
12 голосов
/ 09 сентября 2011

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

Джанго: версия 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 для генерации моделей ...

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

Ответы [ 4 ]

15 голосов
/ 02 октября 2013

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

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

}
4 голосов
/ 10 сентября 2011

MySQL документы произнесите это:

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

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

3 голосов
/ 19 декабря 2012

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

ALTER TABLE table_name ENGINE = engine_type;

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

0 голосов
/ 12 сентября 2011

Я проследил источник проблемы.При создании 2 таблиц InnoDB с отношением внешнего ключа столбец внешнего ключа должен быть явно проиндексирован до MySQL 4.1.2 .Используя ORM в Django, это можно сделать с помощью опции 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, при попытке произойдет ошибка 150выполнить оператор ALTER TABLE.Но если сначала выдается оператор CREATE INDEX, все работает как шарм.Насколько я могу судить, единственный обходной путь для этого - создать свою собственную таблицу вручную, а затем использовать inspectdb для генерации моделей.

Также я создал новый билет Django .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...