在Django中加载fixture时出现contenttypes的问题

时间:2009-05-12 17:02:15

标签: mysql django django-models fixtures mysql-error-1062

由于内容类型冲突,我无法将Django fixtures加载到我的MySQL数据库中。首先,我尝试从我的应用程序转储数据,如下所示:

./manage.py dumpdata escola > fixture.json

但我不断错过外键问题,因为我的应用程序“escola”使用其他应用程序中的表。我一直在添加额外的应用程序,直到我做到这一点:

./manage.py dumpdata contenttypes auth escola > fixture.json

现在,当我尝试将数据作为测试夹具加载时,问题是以下约束违规:

IntegrityError: (1062, "Duplicate entry 'escola-t23aluno' for key 2")

似乎问题是Django正在尝试动态地重新创建具有与fixture中的主键值冲突的不同主键值的contenttypes。这似乎与此处记录的错误相同:http://code.djangoproject.com/ticket/7052

问题是推荐的解决方法是转储我正在做的contenttypes应用程序!?是什么赋予了?如果它有所不同,我确实有一些自定义模型权限,如下所示:http://docs.djangoproject.com/en/dev/ref/models/options/#permissions

15 个答案:

答案 0 :(得分:134)

manage.py dumpdata --natural将使用更持久的外键表示。在django,他们被称为“自然键”。例如:

  • Permission.codename用于支持Permission.id
  • User.username用于支持User.id

了解详情:natural keys section in "serializing django objects"

dumpdata的其他一些有用的论据:

  • --indent=4让人类可读。
  • -e sessions排除会话数据
  • -e admin排除管理员网站上管理员操作的历史记录
  • -e contenttypes -e auth.Permission排除每次在syncdb期间自动从架构重新创建的对象。只能与--natural一起使用,否则您最终可能会出现严重对齐的ID号。

答案 1 :(得分:33)

是的,这真的很烦人。有一段时间我通过在加载fixture之前对contenttypes应用程序执行“manage.py reset”来解决这个问题(以摆脱与转储版本不同的自动生成的contenttypes数据)。这很有效,但最终我厌倦了麻烦,完全放弃了直接的SQL转储(当然,你失去了数据库的可移植性)。

更新 - 最好的答案是使用--natural标记dumpdata,如下面的答案所示。当我写下这个答案时,那个标志还不存在。

答案 2 :(得分:30)

在创建fixture时尝试跳过contenttypes:

./manage.py dumpdata --exclude contenttypes > fixture.json

在类似的单元测试情况下,它对我有用,你对内容类型的洞察确实有帮助!

答案 3 :(得分:24)

这里的答案都是旧的...截至2017年,最佳答案是:

manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4

答案 4 :(得分:10)

我在测试用例中通过在加载转储文件之前从单元测试中重置contenttypes应用程序来解决此问题。 Carl建议使用manage.py命令,我只使用call_command方法做同样的事情:

>>> from django.core import management
>>> management.call_command("flush", verbosity=0, interactive=False)
>>> management.call_command("reset", "contenttypes", verbosity=0, interactive=False)
>>> management.call_command("loaddata", "full_test_data.json", verbosity=0)

我的full_test_data.json fixture包含与其余测试数据对应的contenttypes应用转储。通过在加载前重置应用,可以防止重复键IntegrityError

答案 5 :(得分:10)

我没有使用MySQL,而是将一些数据从实时服务器导入sqlite。在执行contenttypes之前清除loaddata应用数据可以解决问题:

from django.contrib.contenttypes.models import ContentType
ContentType.objects.all().delete()
quit()

然后

python manage.py loaddata data.json

答案 6 :(得分:6)

python manage.py dumpdata --natural-primary --exclude=contenttypes --exclude=auth.Permission --exclude=admin.logentry --exclude=sessions.session --indent 4 > initial_data.json

这对我有用。在这里,我排除了实际模型的一切。

  • 如果您看到除了您创建的模型之外的任何其他模型,您可以安全地排除这些模型。这种方法的一个缺点是您在日志数据和auth数据上都会松动。

答案 7 :(得分:3)

您需要使用自然键来表示任何外键和多对多关系。此外,最好在session应用程序中排除sessions表,在logentry应用程序中排除admin表。

Django 1.7 +

python manage.py dumpdata --natural-foreign --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json

Django <1.7

python manage.py dumpdata --natural --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json

根据Django documentation--natural在1.7版中已被弃用,因此应改为使用选项--natural-foreign

您还可以在此对象的序列化数据中省略主键,因为可以在反序列化期间通过传递--natural-primary标志来计算主键。

python manage.py dumpdata --natural-foreign --natural-primary --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json

答案 8 :(得分:1)

我要给出另一个我刚才想到的答案。也许它会帮助OP,也许它会帮助别人。

我有一个多对多的关系表。它有一个主键和其他表的两个外键。我发现如果我在fixture中有一个条目,其中两个外键与表中已有不同 pk的另一个条目相同,则它将失败。 M2M关系表对于两个外键具有“唯一的”。

因此,如果它是一个破坏的M2M关系,请查看它添加的外键,查看您的数据库以查看该对FK是否已经列在不同的PK下。

答案 9 :(得分:1)

这真的非常令人讨厌......我每次都被它咬了。

我尝试使用--exclude contenttypes和--natural dumpdata,我总是遇到问题..

最适合我的是在syncdb之后执行truncate table django_content_type;然后加载数据。

当然,对于initial_data.json,自动加载你是个淘气球。

答案 10 :(得分:1)

有时候我遇到过类似的错误。原来我在创建必要的表之前尝试加载灯具。所以我做了:

$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py loaddata fixtures/initial_data.json

它就像一个魅力

答案 11 :(得分:1)

./manage.py dumpdata app.Model --natural-foreign

会改变

  "content_type": 123

  "content_type": [
    "app_label",
    "model"
  ],

夹具适用于TestCase现在

答案 12 :(得分:1)

Django 2.2.5

python manage.py dumpdata --exclude=contenttypes > datadump.json

它帮助了我

答案 13 :(得分:0)

就我而言,我已经从auth./manage.py dumpddata auth > fixtures/auth.json)中转储了数据,以将夹具用于测试目的。

开发工作继续进行,我删除了在models.py中定义的大多数模型,这是我开始看到这个烦人的问题的时候。

我的解决方案是再次重新生成auth.json固定装置。这个已经删除了auth.permission中与我以前使用的旧模型相关的很多条目。

答案 14 :(得分:0)

我从上面尝试了所有方法,没有任何方法适合我。我必须排除完整的身份验证模型,然后才能正常工作。

python manage.py dumpdata --natural-primary --exclude=contenttypes --exclude=auth --exclude=admin.logentry --exclude=sessions.session --indent 4 > live.json