MySQL 在 Django 中加载夹具时的内容类型问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/853796/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 13:15:40  来源:igfitidea点击:

Problems with contenttypes when loading a fixture in Django

mysqldjangodjango-modelsfixturesmysql-error-1062

提问by gerdemb

I am having trouble loading Django fixtures into my MySQL database because of contenttypes conflicts. First I tried dumping the data from only my app like this:

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

./manage.py dumpdata escola > fixture.json

but I kept getting missing foreign key problems, because my app "escola" uses tables from other applications. I kept adding additional apps until I got to this:

但是我一直缺少外键问题,因为我的应用程序“escola”使用了其他应用程序中的表。我一直在添加其他应用程序,直到我做到这一点:

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

Now the problem is the following constraint violation when I try to load the data as a test fixture:

现在,当我尝试将数据作为测试装置加载时,问题是以下约束冲突:

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

It seems the problem is that Django is trying to dynamically recreate contenttypes with different primary key values that conflict with the primary key values from the fixture. This appears to be the same as bug documented here: http://code.djangoproject.com/ticket/7052

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

The problem is that the recommended workaround is to dump the contenttypes app which I'm already doing!? What gives? If it makes any difference I do have some custom model permissions as documented here: http://docs.djangoproject.com/en/dev/ref/models/options/#permissions

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

回答by Ski

manage.py dumpdata --naturalwill use a more durable representation of foreign keys. In django they are called "natural keys". For example:

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

  • Permission.codenameis used in favour of Permission.id
  • User.usernameis used in favour of User.id
  • Permission.codename用于支持 Permission.id
  • User.username用于支持 User.id

Read more: natural keys section in "serializing django objects"

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

Some other useful arguments for dumpdata:

其他一些有用的论据dumpdata

  • --indent=4make it human readable.
  • -e sessionsexclude session data
  • -e adminexclude history of admin actions on admin site
  • -e contenttypes -e auth.Permissionexclude objects which are recreated automatically from schema every time during syncdb. Only use it together with --naturalor else you might end up with badly aligned id numbers.
  • --indent=4使其具有人类可读性。
  • -e sessions排除会话数据
  • -e admin排除管理站点上管理操作的历史记录
  • -e contenttypes -e auth.Permission排除每次在syncdb. 只能与它一起使用--natural,否则最终可能会导致 ID 编号严重对齐。

回答by Carl Meyer

Yes, this is really irritating. For a while I worked around it by doing a "manage.py reset" on the contenttypes app prior to loading the fixture (to get rid of the automatically-generated contenttypes data that differed from the dumped version). That worked, but eventually I got sick of the hassles and abandoned fixtures entirely in favor of straight SQL dumps (of course, then you lose DB portability).

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

update- the best answer is to use the --naturalflag to dumpdata, as noted in an answer below. That flag did not exist yet when I wrote this answer.

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

回答by Evgeny

Try skipping contenttypes when creating fixture:

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

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

It worked for me in a similar situation for unit tests, your insight regarding the contenttypes really helped!

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

回答by HelloWorld

The answers here all old... As of 2017, the best answer is:

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

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

回答by MadeOfAir

I was not using MySQL but instead importing some data from a live server into sqlite. Clearing the contenttypesapp data before performing loaddatadid the trick:

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

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

And then

进而

python manage.py loaddata data.json

回答by Jesse L

I have resolved this issue in my test cases by resetting the contenttypes app from the unit test prior to loading my dump file. Carl suggested this already using the manage.pycommand and I do the same thing only using the call_commandmethod:

通过在加载转储文件之前从单元测试中重置 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)

My full_test_data.jsonfixture contains the contenttypes app dump that corresponds to the rest of the test data. By resetting the app before loading, it prevents the duplicate key IntegrityError.

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

回答by Ojas Kale

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

This works for me. Here I am excluding everything bubt the actual models.

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

  • If you see any other model other than the models that you created you can safely exclude those. One drawback of this approach is you loose on log data as well as auth data.
  • 如果您看到除您创建的模型之外的任何其他模型,您可以安全地排除这些模型。这种方法的一个缺点是您会丢失日志数据和身份验证数据。

回答by lmiguelvargasf

You need to use natural keys to represent any foreign key and many-to-many relationships. Moreover, it might be a good idea to exclude the sessiontable in the sessionsapp, and the logentrytable in the adminapp.

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

Django 1.7+

姜戈 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

姜戈 <1.7

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

According to the Django documentation, --naturalhas been deprecated in version 1.7, so the option --natural-foreignshould be used instead.

根据Django 文档--natural已在 1.7 版中弃用,因此--natural-foreign应改用该选项。

You can also omit the primary key in the serialized data of this object since it can be calculated during deserialization by passing the --natural-primaryflag.

您还可以省略此对象的序列化数据中的主键,因为它可以在反序列化期间通过传递--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

回答by Igor Z

Django 2.2.5

Django 2.2.5

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

it helped me

它帮助了我

回答by Daniil Mashkin

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

will change

将改变

  "content_type": 123

to

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

And fixture works for TestCasenow

和夹具TestCase现在工作