Django的syncdb因MySQL errno:150而失败

Red*_*ood 12 python mysql django

首先,这是我目前的设置:

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)")
Run Code Online (Sandbox Code Playgroud)

据我所知,它与InnoDB处理外键的方式有关.这是我的设置文件的样子:

DATABASES = {
    'default': {
        ....
        'OPTIONS':  { 'init_command': 'SET table_type=INNODB;', 'charset': 'latin1'}, 
    },
}
Run Code Online (Sandbox Code Playgroud)

如果未指定"SET table_type = INNODB",则一切都顺利进行.我在网上四处看看,似乎InnoDB引擎不喜欢SQL Django正在生成的东西

现在,我发现的唯一工作就是自己创建表,并使用inspectDB生成模型......

有没有解决这个问题?谢谢!

Pho*_*beB 15

使用Django 1.5,错误是mysql创建表与Innodb作为默认引擎.解决方案是将以下内容添加到数据库的设置中,这会产生约束问题:

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

}
Run Code Online (Sandbox Code Playgroud)


Red*_*ood 0

我追查了问题的根源。在 MySQL 4.1.2 之前,当创建 2 个具有外键关系的 InnoDB 表时,必须显式对外键列建立索引。db_index=True使用 Django 的 ORM,可以通过使用外键字段中的选项来完成此操作。然而,在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)
Run Code Online (Sandbox Code Playgroud)

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;  
Run Code Online (Sandbox Code Playgroud)

如果您尝试使用 MySQL 4.0 运行此代码,则在尝试执行该ALTER TABLE语句时将出现 errno 150。但如果CREATE INDEX先发表声明,一切都会顺利进行。据我所知,唯一的解决方法是手动创建自己的表,然后使用它inspectdb来生成模型。

另外,我创建了一个新的Django 票证