简体   繁体   English

Django 1.8 应用程序初始迁移神秘失败,原因是错误号:150“外键约束形成不正确”

[英]Django 1.8 app mysteriously fails with initial migration due to errno: 150 "Foreign key constraint is incorrectly formed"

I'm writing an app in django 1.8 with python 3.4 and I'm encountering an issue with using MySQL as the database backend which has got me completely stumped.我在 django 1.8 和 python 3.4 中编写了一个应用程序,我遇到了使用 MySQL 作为数据库后端的问题,这让我完全被难住了。

When I start off with a new database and call./manage.py migrate (or syncdb) and it tries to create the initial database, I get the following traceback:当我从一个新数据库开始并调用 ./manage.py migrate(或 syncdb)并尝试创建初始数据库时,我得到以下回溯:

(virtualenv)~/projects/projmoj (master ✘)✹✭ ᐅ ./manage.py migrate
Operations to perform:
  Synchronize unmigrated apps: allauth, rest_framework, registration, rest_auth, projmoj, messages, project, staticfiles
  Apply all migrations: contenttypes, sites, sessions, task, auth, admin, authtoken, static_precompiler, account
Synchronizing apps without migrations:
  Creating tables...
    Creating table project_project
    Creating table project_membership
    Running deferred SQL...
Traceback (most recent call last):
  File "/home/tobbe/projects/projmoj/virtualenv/lib/python3.4/site-packages/django/db/backends/utils.py", line 62, in execute
    return self.cursor.execute(sql)
  File "/home/tobbe/projects/projmoj/virtualenv/lib/python3.4/site-packages/django/db/backends/mysql/base.py", line 124, in execute
    return self.cursor.execute(query, args)
  File "/home/tobbe/projects/projmoj/virtualenv/lib/python3.4/site-packages/MySQLdb/cursors.py", line 220, in execute
    self.errorhandler(self, exc, value)
  File "/home/tobbe/projects/projmoj/virtualenv/lib/python3.4/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorvalue
  File "/home/tobbe/projects/projmoj/virtualenv/lib/python3.4/site-packages/MySQLdb/cursors.py", line 209, in execute
    r = self._query(query)
  File "/home/tobbe/projects/projmoj/virtualenv/lib/python3.4/site-packages/MySQLdb/cursors.py", line 371, in _query
    rowcount = self._do_query(q)
  File "/home/tobbe/projects/projmoj/virtualenv/lib/python3.4/site-packages/MySQLdb/cursors.py", line 335, in _do_query
    db.query(q)
  File "/home/tobbe/projects/projmoj/virtualenv/lib/python3.4/site-packages/MySQLdb/connections.py", line 280, in query
    _mysql.connection.query(self, query)
_mysql_exceptions.OperationalError: (1005, 'Can\'t create table `tasks`.`#sql-1c32_9` (errno: 150 "Foreign key constraint is incorrectly formed")')

This error happens when I do the same on a web hosting service, it works however using sqlite on both the hosting service and localhost.当我在 web 托管服务上执行相同操作时会发生此错误,但它可以在托管服务和本地主机上使用 sqlite。

I have no migrations, and these are my models:我没有迁移,这些是我的模型:

class Project(models.Model):
  name = models.CharField(max_length = 32) 
  description = models.TextField(null=True, blank=True)
  creation_date = models.DateTimeField(auto_now_add=True)

  def get_owner(self):
    return self.members.filter(status=OWNER).first().user

  def get_membership(self, user):
    return self.members.filter(user=user).first()

  def __str__(self):
    return str(self.name) + " - by " + str(self.get_owner().username)

class Membership(models.Model):
  user = models.ForeignKey(User, related_name='joined_projects')
  project = models.ForeignKey(Project, related_name='members')
  status = models.PositiveSmallIntegerField(choices=MEMBER_STATUS)
  join_date = models.DateTimeField(auto_now_add=True)

  def __str__(self):
    return str(self.user.username)

class Sprint(models.Model):
  name = models.CharField(max_length = 32, null=True, blank=True)
  start_date = models.DateTimeField()
  due_date = models.DateTimeField(null=True, blank=True)
  project = models.ForeignKey(Project, related_name='sprints')
  status = models.PositiveSmallIntegerField(choices=SPRINT_STATUS, default=PLANNING)

  def __str__(self):
    return str(self.name) + " - " + str(self.project)

class Category(models.Model):
  name = models.CharField(max_length = 32) 
  project = models.ForeignKey(Project, related_name='categories')

  def __str__(self):
    return str(self.name) + " - " + str(self.project)

class Goal(models.Model):
  name = models.CharField(max_length = 32) 
  description = models.TextField(null=True, blank=True)
  project = models.ForeignKey(Project, related_name='goals')
  completion = models.PositiveSmallIntegerField(choices=COMPLETION, default=NOT_COMPLETED)

  def __str__(self):
    return str(self.name) + " - " + str(self.project)

class Task(models.Model):
  name = models.CharField(max_length = 64)
  description = models.TextField(null=True, blank=True)
  project = models.ForeignKey(Project, related_name='tasks')
  category = models.ForeignKey(Category, related_name='tasks', null=True, blank=True)
  goal = models.ForeignKey(Goal, related_name='tasks', null=True, blank=True)
  creation_date = models.DateTimeField(auto_now_add=True)
  sprint = models.ForeignKey(Sprint, related_name='tasks', null=True, blank=True)
  status = models.PositiveSmallIntegerField(choices=TASK_STATUS, default=WAITING)
  dedicated_hours = models.DecimalField(max_digits=6, decimal_places=2, null=True, blank=True)
  assigned_worker = models.ForeignKey(User, null=True, blank=True)
  priority = models.PositiveSmallIntegerField(choices=PRIORITY, default=NORMAL)

  def __str__(self):
    return str(self.name) + " - " + str(self.project)

class HourReport(models.Model):
  task = models.ForeignKey(Task, related_name='hour_reports')
  worker = models.ForeignKey(User, related_name='hour_reports')
  hours_spent = models.DecimalField(max_digits=6, decimal_places=2)
  date = models.DateTimeField(auto_now_add=True)

  def __str__(self):
    return str(self.hours_spent) + " on " + str(self.task)

My database settings:我的数据库设置:

DATABASES = { 
  'default': {
      'ENGINE': 'django.db.backends.mysql',
      'NAME': 'tasks',
      'USER': 'root',
      'PASSWORD': 'mysqlmysql',
      'HOST': 'localhost',
  }
}

Versions etc:版本等:

  • Django 1.8 Django 1.8
  • Python 3.4 Python 3.4
  • Default storage engine: InnoDB默认存储引擎:InnoDB
  • Mysqlclient 1.3.6 Mysql客户端1.3.6
  • Server: MySQL 5.5.42 on Amazon RDS (at web hosting)服务器:Amazon RDS 上的 MySQL 5.5.42(在 web 托管)
  • Server: 10.0.21-MariaDB-log MariaDB Server (localhost)服务器:10.0.21-MariaDB-log MariaDB 服务器(本地主机)

When googling it seems like this error is often when people stuff up their manual SQL code, but I am doing it all automatically through django.谷歌搜索时,这个错误似乎经常出现在人们填充他们的手动 SQL 代码时,但我通过 django 自动完成。

Any ideas?有任何想法吗?

The log is telling you that you have not created migrations for your project app.日志告诉您尚未为project应用程序创建迁移。 You should create migrations for the app before running migrate.您应该在运行迁移之前为应用程序创建迁移。

./manage.py makemigrations project
./manage.py migrate

Since it's a new database, you'd be better to completely reset it before creating and applying the migrations, otherwise you'll have to manually deal with its current inconsistent state.由于它是一个新数据库,您最好在创建和应用迁移之前完全重置它,否则您将不得不手动处理其当前不一致的状态。

According to the Django documentation MySQL notes.根据 Django 文档MySQL 注释。 Storage engine 存储引擎

If you upgrade an existing project to MySQL 5.5.5 and subsequently add some tables, ensure that your tables are using the same storage engine (ie MyISAM vs. InnoDB ).如果您将现有项目升级到MySQL 5.5.5并随后添加一些表,请确保您的表使用相同的存储引擎(即MyISAMInnoDB )。 Specifically, if tables that have a ForeignKey between them use different storage engines, you may see an error like the following when running migrate :具体来说,如果表之间有一个ForeignKey使用不同的存储引擎,您可能会在运行migrate时看到如下错误:

 _mysql_exceptions.OperationalError: ( 1005, "Can't create table '\\\\db_name\\\\.#sql-4a8_ab' (errno: 150)" )

Stop you backend and do backup.停止您的后端并进行备份。 Than change storage engine for tables from MyISAM to InnoDB.将表的存储引擎从 MyISAM 更改为 InnoDB。 It's fix the problem.这是解决问题。

Also in the MySQL docs ( B.3 Server Error Codes and Messages chapter) specified about this error:同样在 MySQL 文档( B.3 服务器错误代码和消息章节)中指定了关于此错误:

Error: 1005 SQLSTATE: HY000 (ER_CANT_CREATE_TABLE)错误:1005 SQLSTATE: HY000 (ER_CANT_CREATE_TABLE)

Message: Can't create table '%s' (errno: %d - %s)消息:无法创建表“%s”(错误号:%d - %s)

InnoDB reports this error when a table cannot be created.当无法创建表时,InnoDB 会报告此错误。 If the error message refers to error 150, table creation failed because a foreign key constraint was not correctly formed.如果错误消息涉及错误 150,则表创建失败,因为外键约束未正确形成。 If the error message refers to error −1, table creation probably failed because the table includes a column name that matched the name of an internal InnoDB table.如果错误消息指向错误 -1,则表创建可能失败,因为该表包含与内部 InnoDB 表名称匹配的列名称。

It's also possible when running python manage.py migrate to get that error of运行 python manage.py migrate时也有可能得到该错误

_mysql.connection.query(self, query) _mysql.connection.query(自我,查询)

django.db.utils.OperationalError: (1005, 'Can\\'t create table > codelabs . django_admin_log (errno: 150 "Foreign key constraint is incorrectly formed")') django.db.utils.OperationalError: (1005, 'Can\\'t create table > codelabs django_admin_log (errno: 150 "外键约束形成不正确")')

due to having wrong information in settings.py regarding the DATABASES.由于 settings.py 中关于 DATABASES 的信息有误。 For instances, if in your database your table has the name tiago p eres and in your settings.py you're refering the NAME to be tiago P eres , that error will show up.对于情况下,如果在你的数据库表中有名字蒂亚戈p ERES并在settings.py你闯民宅的名字蒂亚戈P ERES,该错误会显示出来。 To fix it, just use the correct NAME and run again python manage.py migrate .要修复它,只需使用正确的 NAME 并再次运行python manage.py migrate

I also ran into this issue today and read articles and StackOverflow which didn't solve the issue.我今天也遇到了这个问题并阅读了没有解决问题的文章和 StackOverflow。 Then I deleted my database as there was nothing special and removed all migration files and started the migration process again.然后我删除了我的数据库,因为没有什么特别的,并删除了所有迁移文件并再次开始迁移过程。 Issue solved.问题解决了。

Look at the output of the command SHOW ENGINE INNODB STATUS in MySql or MariaDB console client ( mariadb link , mysql link ).查看 MySql 或 MariaDB 控制台客户端中命令SHOW ENGINE INNODB STATUS的 output( mariadb 链接mysql 链接)。 It`s more informative.它的信息量更大。 For example, it showed me this message:例如,它向我展示了这条消息:

...
------------------------
LATEST FOREIGN KEY ERROR
------------------------
2021-09-20 18:27:08 7faea3ad1700 Error in foreign key constraint of table `my_db`.`django_admin_log`:
Alter  table `my_db`.`django_admin_log` with foreign key constraint failed. Referenced table `my_db`.`profiles_userprofile` not found in the data dictionary near ' FOREIGN KEY (`user_id`) REFERENCES `profiles_userprofile` (`id`)'.
...

It said to me that I forgot to create migrations.它对我说我忘了创建迁移。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM