ChatGPT解决这个技术问题 Extra ChatGPT

在 Django 中加载固定装置时出现内容类型问题

由于内容类型冲突,我无法将 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


S
Ski

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

Permission.codename 用于 Permission.id

User.username 用于 User.id

阅读更多:natural keys section in "serializing django objects"

dumpdata 的其他一些有用参数:

--indent=4 使其易于阅读。

-e 会话排除会话数据

-e admin 排除管理站点上的管理操作历史记录

-e contenttypes -e auth.Permission 排除在 syncdb 期间每次从架构自动重新创建的对象。仅将它与 --natural 一起使用,否则您最终可能会得到错误对齐的 id 编号。


@skyjur 为什么总是将 -e contenttypes -e auth.permission--natural 一起使用?我只是尝试不使用 --natural 选项并且它有效。 documentation here 还表示,如果 DUMPING auth.permissioncontenttypes 应使用此选项。
@winirvana 因为在您从头开始并执行 syncdb 之后,新创建的 ContentTypePermission 不能保证获得与以前相同的 id。您的数据转储包含可能引用另一个数据库上您将加载数据的不同对象的 ID。由于以下原因之一,它可能对您有用:1)您的数据没有对这些对象的任何引用 2)Permission/ContentTypes 的原始 id 被保留 3)您的 loaddata 成功但实际上由于对象而导致数据损坏引用错误的对象而你还不知道
标志 --natural 现在已弃用,取而代之的是 --natural-foreign(和 --natural-primary
最终命令可能是:manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4 > project_dump.json
--natural 现在已被完全删除,而不仅仅是弃用。请改用 --natural-foreign--natural-primary
S
SmallChess

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

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

C
Carl Meyer

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

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


我也遇到了这个问题,重置内容类型应用程序也对我有用。谢谢你的提示!
你是如何重置它们的?在测试用例类中?请给我一个例子
我不使用固定装置进行单元测试,我通常在 setup() 方法中使用 ORM 创建测试数据,因为它更容易与测试保持同步。所以我从来不需要在 TestCase 类中这样做,尽管我确信如果你在 Django 的 TestCase 类的代码中四处寻找,你可以弄清楚如何在 syncdb 之后和在子类中加载夹具之前进行重置。对我来说,它只是“./manage.py loaddata my_fixture”之前的 bash 脚本中的“./manage.py reset contenttypes”。
E
Evgeny

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

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

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


M
MadeOfAir

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

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

接着

python manage.py loaddata data.json

django.core.exceptions.ImproperlyConfigured:请求设置 INSTALLED_APPS,但未配置设置。您必须在访问设置之前定义环境变量 DJANGO_SETTINGS_MODULE 或调用 settings.configure()。
它可能在自定义管理命令的句柄中效果最好。
J
Jesse L

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


l
lmiguelvargasf

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

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

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

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

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


D
Daniil Mashkin
./manage.py dumpdata app.Model --natural-foreign

将改变

  "content_type": 123

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

夹具现在适用于 TestCase


h
h3.

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

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

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

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


对我来说,在 loaddata 之前截断表只会导致不同的错误。这种技术不走运。
I
Igor Z

Django 2.2.5

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

它帮助了我


加载数据时会出现问题,可能与新数据库中的内容类型不匹配
o
orblivion

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

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

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


J
James Wanderi

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

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

它就像一个魅力


C
Chandra Shekhar Pandey

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

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

P
Pablo Castellano

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

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

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


D
Don Bobskiy

我已经通过添加我的测试 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()

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅