关于python:创建表时Django MySQL错误

Django MySQL error when creating tables

我正在使用MySQL DB构建一个django应用程序。 当我第一次运行'python manage.py migrate'时,会创建一些表,然后会出现一些错误。 带来的错误是:

django.db.utils.IntegrityError: (1215, 'Cannot add foreign key
constraint')

当我运行这个MySQL命令时 -

SHOW ENGINE INNODB STATUS\G,

我明白了>>>

1
2
3
4
2015-02-17 14:33:17 7f10891cf700 Error in foreign key constraint of table movie_store/#sql-4f1_66:
 FOREIGN KEY (`group_id`) REFERENCES `auth_group` (`id`):
Cannot resolve table name close to:
 (`id`)

完整的追溯是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
Creating tables...
    Creating table users
    Creating table merchant
    Creating table celery_taskmeta
    Creating table celery_tasksetmeta
    Creating table djcelery_intervalschedule
    Creating table djcelery_crontabschedule
    Creating table djcelery_periodictasks
    Creating table djcelery_periodictask
    Creating table djcelery_workerstate
    Creating table djcelery_taskstate
    Creating table post_office_email
    Creating table post_office_log
    Creating table post_office_emailtemplate
    Creating table post_office_attachment
    Running deferred SQL...
Traceback (most recent call last):
  File"manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File"/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
    utility.execute()
  File"/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 330, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File"/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 390, in run_from_argv
    self.execute(*args, **cmd_options)
  File"/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 441, in execute
    output = self.handle(*args, **options)
  File"/usr/local/lib/python2.7/dist-packages/django/core/management/commands/migrate.py", line 173, in handle
    created_models = self.sync_apps(connection, executor.loader.unmigrated_apps)
  File"/usr/local/lib/python2.7/dist-packages/django/core/management/commands/migrate.py", line 309, in sync_apps
    cursor.execute(statement)
  File"/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 80, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File"/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File"/usr/local/lib/python2.7/dist-packages/django/db/utils.py", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File"/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 63, in execute
    return self.cursor.execute(sql)
  File"/usr/local/lib/python2.7/dist-packages/django/db/backends/mysql/base.py", line 124, in execute
    return self.cursor.execute(query, args)
  File"/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 174, in execute
    self.errorhandler(self, exc, value)
  File"/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
django.db.utils.IntegrityError: (1215, 'Cannot add foreign key constraint')


这将有效

1
2
python manage.py migrate auth
python manage.py migrate

由于其他迁移的问题在auth之前运行,因此这将确保"authtools"的迁移首先运行


您是否为所有应用创建了迁移?如果没有,您可能会遇到以错误的顺序创建数据库表的问题,这将给您带来此错误。

如果您有一个现有的Django 1.7项目,那么您需要创建初始迁移文件,然后伪造初始迁移,如此处所述

https://docs.djangoproject.com/en/1.8/topics/migrations/#adding-migrations-to-apps

使用创建迁移

1
$ python manage.py make migrations your_app_label

然后伪造应用程序

1
$  python manage.py migrate --fake-initial your_app_label


我使用时遇到了这个问题:

1
$ python manage.py test

如果您没有为具有django.contrib.auth.models.User的Foreignkey字段的模型进行迁移,则会导致该问题。

如果你启用--keepdb,你会发现没有auth_user表和其他一些django的管理表。

让我们追踪整个问题:

跑:

1
$ python manage.py test --verbosity=3

您可以看到之后引发的foreigngkey约束异常

Running deferred SQL...

延迟的sql类似于

"ALTER TABLE xxx ADD CONSTRAINT xx FOREIGN KEY (x) REFERENCES auth_user"

检查django / core / management / commands / migrate.py的源代码:

1
2
for statement in deferred_sql:
    cursor.execute(statement)

defered_sql来自manifest.items() for循环,

manifest来自all_models

all_models来自app_labels中的app_config.label。

这是通过的论点

1
self.sync_apps(connection, executor.loader.unmigrated_apps)

因此,executor.loader.unmigrated_apps将包含unmigrated_app的标签,如果你发现有一个外键到Django的auth_user,它会导致Foreignkey约束错误原因,当时没有名为auth_user的表。

解:

假设app是包含那些Foreignkey属性类的模块:

1
2
3
$ python manage.py migrate auth
$ python manage.py migrate
$ python manage.py makemigrations app

并且,如果您有其他模块依赖于app,假设数据库表与app模块具有相同的字段,您需要:

1
$ python manage.py make migrate app --fake


我对外键'author_id'有同样的问题。

解决方案是更改名称

1
author = models.ForeignKey(User, related_name='+')

1
writer = models.ForeignKey(User, related_name='+')

因此,请尝试将您的字段名称更改为不同的字段

1
group

尝试在BitBucket / Pipelines中设置CI时,我遇到了同样的错误。 问题是我没有将迁移文件夹提交到我们的git存储库中,因为Pipelines每次都从头开始重建所有内容,单元测试无法启动。

执行时会创建迁移文件夹:

1
2
python manage.py makemigrations
python manage.py makemigrations <module_name>

运行makemigrations / migrate步骤并确保我们的非测试代码正常工作后,我的测试将起作用。

看起来:

1
python manage.py test

将尝试生成迁移,如果它们当前不存在,但它不能始终正确地获取依赖项,因此您需要确保将迁移文件夹中的自动生成代码提交到源代码存储库。

有关django迁移的更多详细信息,请访问:https://docs.djangoproject.com/en/1.11/topics/migrations/


确保外键和主键的类型相同。

外键必须与外表的主键类型相同。我在外表中有一个bigint,django不知道如何自动创建一个bigint的外键。

通过运行调查迁移失败的原因:
python manage.py sqlmigrate {app_name} {migration_name}

在工作台中运行它,您将看到失败背后的真正错误。

django.db.utils.IntegrityError:(1215,'无法添加外键约束')


有同样的问题,原来Django不知何故升级到v1.8,立即降级为v1.7工作。


如果上述方法不起作用并且您不需要Innodb,则默认为MYISAM工作,因为它没有相同的参照完整性级别:

1
2
3
4
5
6
7
8
9
10
11
DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': 'name',                      
    'USER': 'user',    
    'PASSWORD': 'password',
    'OPTIONS': {
          "init_command":"SET storage_engine=MYISAM",
    }  
  }  
}


在Django 1.8中删除了syncdb命令,而不是syncdb尝试manage.py migrate命令然后表格将创建。之后你必须创建超级用户使用超级用户创建命令或运行manage.py syncdb,它将工作。