117

由于内容类型冲突,我无法将 Django 固定装置加载到我的 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 试图动态地重新创建具有不同主键值的内容类型,这些主键值与夹具中的主键值冲突。这似乎与此处记录的错误相同:http: //code.djangoproject.com/ticket/7052

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

4

16 回答 16

157

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

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

阅读更多:“序列化 django 对象”中的自然键部分

其他一些有用的论点dumpdata

  • --indent=4使其具有人类可读性。
  • -e sessions排除会话数据
  • -e admin排除管理站点上的管理操作历史记录
  • -e contenttypes -e auth.Permission排除每次在syncdb. 只能将它与它一起使用--natural,否则您最终可能会得到错误对齐的 id 编号。
于 2010-11-02T08:17:01.017 回答
39

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

manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4
于 2017-05-05T12:41:37.797 回答
35

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

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

于 2009-05-13T00:58:27.540 回答
32

创建夹具时尝试跳过内容类型:

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

它在单元测试的类似情况下对我有用,您对内容类型的洞察力真的很有帮助!

于 2010-05-30T03:03:37.773 回答
14

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

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

接着

python manage.py loaddata data.json
于 2016-11-12T00:33:33.597 回答
10

我已经在我的测试用例中解决了这个问题,方法是在加载我的转储文件之前从单元测试中重置 contenttypes 应用程序。卡尔已经使用该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夹具包含与其余测试数据相对应的内容类型应用转储。通过在加载之前重置应用程序,它可以防止重复键IntegrityError

于 2010-10-04T13:41:44.497 回答
8

您需要使用自然键来表示任何外键和多对多关系。此外,排除应用程序中的表格和应用程序中的session表格可能是个好主意。sessionslogentryadmin

姜戈 1.7+

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

姜戈 <1.7

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

根据Django 文档--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
于 2018-12-07T04:02:06.690 回答
7
python manage.py dumpdata --natural-primary --exclude=contenttypes --exclude=auth.Permission --exclude=admin.logentry --exclude=sessions.session --indent 4 > initial_data.json

这对我有用。在这里,我排除了除实际模型之外的所有内容。

  • 如果您看到除您创建的模型之外的任何其他模型,您可以安全地排除这些模型。这种方法的一个缺点是您在日志数据和身份验证数据上松散了。
于 2017-06-21T01:51:20.313 回答
3
./manage.py dumpdata app.Model --natural-foreign

将改变

  "content_type": 123

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

夹具TestCase现在可以工作

于 2018-01-25T10:27:35.907 回答
2

真的,真的很烦人..我每次都被这个咬伤。

我尝试使用 --exclude contenttypes 和 --natural 转储数据,但我总是遇到问题..

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

当然,对于 initial_data.json 自动加载,你是个失败者。

于 2011-10-14T14:14:50.553 回答
2

Django 2.2.5

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

它帮助了我

于 2019-09-05T10:20:31.093 回答
1

我将给出我刚刚想出的另一个可能的答案。也许它会帮助OP,也许它会帮助其他人。

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

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

于 2011-10-06T22:42:50.677 回答
1

我尝试了上面的所有方法,对我没有任何作用。我必须排除完整的身份验证模型并且工作正常。

python manage.py dumpdata --natural-primary --exclude=contenttypes --exclude=auth --exclude=admin.logentry --exclude=sessions.session --indent 4 > live.json
于 2020-07-31T13:28:03.787 回答
1

我以前有时也遇到过类似的错误。事实证明,我试图在创建必要的表之前加载固定装置。所以我做了:

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

它就像一个魅力

于 2016-07-05T14:28:35.177 回答
0

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

开发继续进行,我删除了我定义的大部分模型models.py,这就是我开始看到这个烦人的问题的时候。

我的解决方案是再次重新生成 auth.json 夹具。这个已经删除了很多auth.permission与我拥有的旧模型相关的条目。

于 2020-02-05T23:19:22.267 回答
0

我已经通过添加我的测试 setUp 和 tearDown 来解决这个问题

from django.core import management

=====

def setUp(self):
    management.call_command("loaddata", "all-data.yaml", verbosity=0)
    super(login_page_test, self).setUp()

def tearDown(self):
    management.call_command("flush", verbosity=0, interactive=False)
    super(login_page_test, self).setUp()
于 2022-01-07T19:23:48.103 回答