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

use*_*478 100 mysql django django-models fixtures mysql-error-1062

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

./manage.py dumpdata escola > fixture.json
Run Code Online (Sandbox Code Playgroud)

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

./manage.py dumpdata contenttypes auth escola > fixture.json
Run Code Online (Sandbox Code Playgroud)

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

IntegrityError: (1062, "Duplicate entry 'escola-t23aluno' for key 2")
Run Code Online (Sandbox Code Playgroud)

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

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

Ski*_*Ski 142

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号.

  • 最后的命令可能是:`manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4> project_dump.json` (12认同)
  • 标志`--natural`现在被弃用,赞成`--natural-foreign`(和`--natural-primary`) (10认同)
  • @winirvana因为从头开始并执行syncdb后,新创建的`ContentType`和`Permission`不能保证获得与之前相同的id.您的数据转储包含可能引用您将加载数据的anather数据库上的不同对象的ID.由于以下原因之一,它可能对您有用:1)您的数据没有对这些对象的任何引用2)保留了Permission/ContentTypes的原始ID 3)您的loaddata是成功的但是实际上由于对象而导致数据损坏提到错误的对象,你还不知道它 (6认同)
  • `--natural` 现在已被完全删除,而不仅仅是弃用。使用 `--natural-foreign` 或 `--natural-primary` 代替。 (4认同)

Car*_*yer 33

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

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

  • 我不使用灯具进行单元测试,我通常在setup()方法中使用ORM创建测试数据,因为它更容易与测试保持同步.所以我从来没有在TestCase类中做过这个,虽然我确定如果你在Django的TestCase类的代码中探讨,你可以弄清楚如何在syncdb之后和子类中的fixture加载之前进行重置.对我来说,在"./manage.py loaddata my_fixture"之前的bash脚本中只是"./manage.py reset contenttypes". (4认同)
  • 我也遇到了这个问题,重置了为我工作的contenttypes应用程序.谢谢你的提示! (3认同)

Evg*_*eny 30

尝试在创建fixture时跳过contenttypes:

./manage.py dumpdata --exclude contenttypes > fixture.json
Run Code Online (Sandbox Code Playgroud)

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


Sma*_*ess 27

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

manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4
Run Code Online (Sandbox Code Playgroud)


Jes*_*e L 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)
Run Code Online (Sandbox Code Playgroud)

我的full_test_data.jsonfixture包含与其余测试数据相对应的contenttypes app转储.通过在加载前重置应用程序,它可以防止重复键IntegrityError.


Mad*_*Air 10

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

from django.contrib.contenttypes.models import ContentType
ContentType.objects.all().delete()
quit()
Run Code Online (Sandbox Code Playgroud)

然后

python manage.py loaddata data.json
Run Code Online (Sandbox Code Playgroud)


Oja*_*ale 6

python manage.py dumpdata --natural-primary --exclude=contenttypes --exclude=auth.Permission --exclude=admin.logentry --exclude=sessions.session --indent 4 > initial_data.json
Run Code Online (Sandbox Code Playgroud)

这适合我.在这里,我排除了实际模型的一切.

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


lmi*_*asf 6

您需要使用自然键来表示任何外键和多对多关系。此外,排除应用程序中的表和应用程序中的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
Run Code Online (Sandbox Code Playgroud)

姜戈 <1.7

python manage.py dumpdata --natural --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json
Run Code Online (Sandbox Code Playgroud)

根据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
Run Code Online (Sandbox Code Playgroud)