Django 在创建数据库时创建对错误表的外键引用
Django creating foreign key references to the wrong tables on database creation
我清除了 Django 应用程序上的数据库以重新开始。我通过删除数据库文件和现有迁移然后重新 运行 makemigrations
和 migrate
来完成此操作。我当然先备份了数据库。
我很快 运行 遇到问题;在提交表格后,我被告知 The table 'topics__old' does not exist.
我认为这很奇怪,因为我已经命名了我所有的 table 并且那不是其中之一。以下是相关型号:
class Topic(models.Model, FormatDateMixin):
topic_id = models.UUIDField(primary_key=True,
default=uuid.uuid4,
editable=False)
submitted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
comment = models.TextField(max_length=150)
created_date = models.DateTimeField(default=timezone.now)
class Meta:
db_table = 'topics'
class TopicUpdate(models.Model, FormatDateMixin):
update_id = models.UUIDField(primary_key=True,
default=uuid.uuid4,
editable=False)
original_topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
submitted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
comment = models.TextField(max_length=150)
update_date = models.DateTimeField(default=timezone.now)
class Meta:
db_table = 'topic_updates'
我检查了旧工作版本和当前版本的数据库文件,发现以下内容:
原文Table:
CREATE TABLE "topic_updates" ("update_id" char(32) NOT NULL PRIMARY KEY, ... "original_topic_id" char(32) NOT NULL REFERENCES "topics" ("topic_id") DEFERRABLE INITIALLY DEFERRED, ...
新 Table:
CREATE TABLE "topic_updates" ("update_id" char(32) NOT NULL PRIMARY KEY, ... "original_topic_id" char(32) NOT NULL REFERENCES "topics__old" ("topic_id") DEFERRABLE INITIALLY DEFERRED, ...
正如您在创建数据库时看到的那样,Django 在引用外键时将 __old
附加到 table 名称,这会导致应用程序出现错误,因为 topics__old
不存在.
我已经尝试删除所有 __pycache__
文件夹,删除所有迁移文件,重新 运行 makemigrations
和 migrate --run-syncdb
。 None 已解决此问题。
应该注意它确实创建了 table topics
并且与 topics
table 相关的表格按预期工作。为什么会这样?
做了一些 grepping,在 django/db/backends/sqlite3/schema.py
中找到了 __old
,这让我找到了根本原因。
原来这是由对 SQLite 的更新引起的,Django 已经推送了一个修复程序:
https://github.com/django/django/commit/894cb13779e6d092974c873bd2cf1452554d2e06
SQLite 3.26 changed the behaviour of table and column renaming operations to
repoint foreign key references even if foreign key checks are disabled.
This makes the workarounds in place to simulate this behaviour unnecessary on
SQLite 3.26+.
然而,尽管已经超过两周,但这个更新似乎还没有进入 pypi 或 ubuntu/debian 回购协议,所以我不得不删除我的 django 实例和 pip install
来自 git 仓库。
我清除了 Django 应用程序上的数据库以重新开始。我通过删除数据库文件和现有迁移然后重新 运行 makemigrations
和 migrate
来完成此操作。我当然先备份了数据库。
我很快 运行 遇到问题;在提交表格后,我被告知 The table 'topics__old' does not exist.
我认为这很奇怪,因为我已经命名了我所有的 table 并且那不是其中之一。以下是相关型号:
class Topic(models.Model, FormatDateMixin):
topic_id = models.UUIDField(primary_key=True,
default=uuid.uuid4,
editable=False)
submitted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
comment = models.TextField(max_length=150)
created_date = models.DateTimeField(default=timezone.now)
class Meta:
db_table = 'topics'
class TopicUpdate(models.Model, FormatDateMixin):
update_id = models.UUIDField(primary_key=True,
default=uuid.uuid4,
editable=False)
original_topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
submitted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
comment = models.TextField(max_length=150)
update_date = models.DateTimeField(default=timezone.now)
class Meta:
db_table = 'topic_updates'
我检查了旧工作版本和当前版本的数据库文件,发现以下内容:
原文Table:
CREATE TABLE "topic_updates" ("update_id" char(32) NOT NULL PRIMARY KEY, ... "original_topic_id" char(32) NOT NULL REFERENCES "topics" ("topic_id") DEFERRABLE INITIALLY DEFERRED, ...
新 Table:
CREATE TABLE "topic_updates" ("update_id" char(32) NOT NULL PRIMARY KEY, ... "original_topic_id" char(32) NOT NULL REFERENCES "topics__old" ("topic_id") DEFERRABLE INITIALLY DEFERRED, ...
正如您在创建数据库时看到的那样,Django 在引用外键时将 __old
附加到 table 名称,这会导致应用程序出现错误,因为 topics__old
不存在.
我已经尝试删除所有 __pycache__
文件夹,删除所有迁移文件,重新 运行 makemigrations
和 migrate --run-syncdb
。 None 已解决此问题。
应该注意它确实创建了 table topics
并且与 topics
table 相关的表格按预期工作。为什么会这样?
做了一些 grepping,在 django/db/backends/sqlite3/schema.py
中找到了 __old
,这让我找到了根本原因。
原来这是由对 SQLite 的更新引起的,Django 已经推送了一个修复程序: https://github.com/django/django/commit/894cb13779e6d092974c873bd2cf1452554d2e06
SQLite 3.26 changed the behaviour of table and column renaming operations to repoint foreign key references even if foreign key checks are disabled. This makes the workarounds in place to simulate this behaviour unnecessary on SQLite 3.26+.
然而,尽管已经超过两周,但这个更新似乎还没有进入 pypi 或 ubuntu/debian 回购协议,所以我不得不删除我的 django 实例和 pip install
来自 git 仓库。