创建表时Django MySQL错误

Posted

技术标签:

【中文标题】创建表时Django MySQL错误【英文标题】:Django MySQL error when creating tables 【发布时间】:2015-04-18 03:30:44 【问题描述】:

我正在使用 mysql 数据库构建一个 django 应用程序。当我第一次运行“python manage.py migrate”时,一些表创建得很好,然后出现了一些错误。带出来的错误是:

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

当我运行这个 MySQL 命令时 -

显示引擎 INNODB 状态\G,

我明白了>>>

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

完整的回溯是:

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

【问题讨论】:

您可能需要包含正在运行的模型文件 我认为您的 INSTALLED_APPS 中没有包含“django.contrib.auth”。 我有这两个:'django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.auth.middleware.SessionAuthenticationMiddleware', @Denny,在您的 INSTALLED_APPS 中包含 django.contrib.auth 而不是 MIDDLEWARE_CLASSES @Denny- 你能解决这个问题吗? 【参考方案1】:

遇到了同样的问题,结果不知何故 Django 升级到v1.8,立即降级到v1.7 工作。

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

外键“author_id”也有同样的问题。

解决办法是改名

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

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

所以尝试将您的字段名称更改为不同于

group

【讨论】:

【参考方案4】:

您是否为所有应用创建了迁移?如果没有,您很可能会遇到数据库表创建顺序错误的问题,这会导致您出现此错误。

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

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

使用

创建迁移
$ python manage.py make migrations your_app_label

然后伪造应用程序

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

【讨论】:

【参考方案5】:

这会奏效

python manage.py migrate auth
python manage.py migrate

由于其他迁移在身份验证之前运行的问题,因此这将确保“authtools”的迁移首先运行

【讨论】:

请考虑编辑您的帖子,以添加更多关于您的代码的作用以及它为何能解决问题的说明。一个大部分只包含代码的答案(即使它正在工作)通常不会帮助 OP 理解他们的问题。 @JamesLin 我在运行 unittest 时也遇到了这个问题。但是 unittest 每次运行测试时总是重新创建模式,所以我仍然没有找到解决方案。但是我得到了解决这个问题的技巧 1. 运行 unittest(第一次):$python manage.py testcode` 这将创建测试数据库,但在迁移 2 时失败。然后我用 --keepdb $python manage.py test --keepdb 这个重新运行测试您可以运行测试的方式,但是这当然不是回归测试的正确方式。 @hiennt:您的解决方案也对我有用。我在单元测试中遇到了这个错误。但是你有没有找到更好的方法来解决这个问题? @sudshekhar 对我来说同样的问题 工作得非常好。谢谢。【参考方案6】:

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

DATABASES =  
  'default': 
    'ENGINE': 'django.db.backends.mysql',
    'NAME': 'name',                      
    'USER': 'user',     
    'PASSWORD': 'password',
    'OPTIONS': 
           "init_command": "SET storage_engine=MYISAM",
       
     

【讨论】:

现在使用 MyISAM 应该被认为是有害的。【参考方案7】:

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

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

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

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

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

【讨论】:

【参考方案8】:

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

$ python manage.py test

如果您没有将那些具有 Foreignkey 字段的模型迁移到 django.contrib.auth.models.User,则会导致问题。

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


让我们追踪整个问题:

运行:

$ python manage.py test --verbosity=3

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

正在运行延迟 SQL...

延迟的sql类似于

“更改表xxx添加约束xx外键(x)引用auth_user

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

for statement in deferred_sql:
    cursor.execute(statement)

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

manifest来自all_models

all_models 来自 app_labels 中的 app_config.label。

这是由

传递的参数
self.sync_apps(connection, executor.loader.unmigrated_apps)

因此,executor.loader.unmigrated_apps 会包含 unmigrated_app 的标签,如果你碰巧有 Django 的 auth_user 的 Foreignkey,会导致 Foreignkey constrain Error 导致当时没有名为 auth_user 的表。


解决方案:

假设app 是包含这些外键属性类的模块:

$ python manage.py migrate auth
$ python manage.py migrate
$ python manage.py makemigrations app

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

$ python manage.py make migrate app --fake

【讨论】:

+1 用于挖掘源代码。但是这个解决方案对manage.py test 有什么帮助?通过交换makemigrations的顺序? @Sean =。= 我的意思是在我们运行python manage.py test之前,我们应该为那些包含Django默认模型的外键的应用程序模型进行迁移。例如 django.contrib.auth.User 的外键。否则,它将引发此异常。例如,如果您丢失了应用程序的迁移文件夹,您将无法成功运行python manage.py test【参考方案9】:

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

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

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

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

看来:

python manage.py test 

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

更多关于 django 迁移的细节可以在这里找到:https://docs.djangoproject.com/en/1.11/topics/migrations/

【讨论】:

【参考方案10】:

我在针对 MySQL 数据库的 Django 库上运行测试时遇到了类似的问题(以避免Django 2.2 incompatibilities with CentOS 7)。这与问题carton.swing's answer 地址类似,但采用不同的方法来解决问题。

关于我正在测试的库的几点说明:

没有定义任何模型,但测试套件定义了模型用于测试目的李> 测试套件依赖于未定义模型的外键,特别是auth.User 模型。

在查看old Django ticket 后,我注意到了这个回复:

您的问题是未迁移的应用程序(authtoken)依赖(具有 FK 到)迁移的应用程序(主)。这是众所周知的禁忌。

(我找不到任何其他关于这是“众所周知的禁忌”的引用。)由于测试套件定义了一些模型,并且还使用了 Django 提供的auth.User,我猜想测试运行器(pytest,在这种情况下)迁移了测试套件中定义的模型,但没有迁移auth.User。为了对此进行测试,我在我的测试套件上关闭了迁移(对于 pytest-django,这只需要添加 --no-migrations flag),从而解决了这个问题。

【讨论】:

【参考方案11】:

遇到了类似的情况

django.db.utils.OperationalError: (1824, "Failed to open the referenced table 'auth_user'")

首先,我通过确保正确完成所有迁移来解决这个问题,每个应用程序都有其相应的迁移文件夹以及其中的 __init__.py 文件。

之后,我在数据库中的另一个表中遇到了类似的问题,引发了另一个错误,这阻止了我开始测试。 我通过删除 django_migrations 表中的所有记录来解决它,删除所有迁移文件(如果你同意的话)。然后我跑

python manage.py makemigrations

python manage.py migrate --fake

处理迁移的所有废话:)

【讨论】:

以上是关于创建表时Django MySQL错误的主要内容,如果未能解决你的问题,请参考以下文章

恢复 Django-mailer 数据库时出现 MySQL 错误 1118(行大小太大)

MySQL:无法创建表(错误号:150)

MySQL:无法创建表(错误号:150)

MySQL:无法创建表(错误号:150)

MySQL:无法创建表(错误号:150)

MySQL:无法创建表(错误号:150)