Django loaddata 唯一约束失败。

23

我正在使用一个空的数据库(UserUserProfile表已被创建但未填充),运行以下命令:python manage.py loaddata 'path/to/mydata.json',但是我遇到了以下错误:

django.db.utils.IntegrityError: Problem installing fixture 'path/to/mydata.json': Could not load myapp.UserProfile(pk=1): UNIQUE constraint failed: myapp_userprofile.user_id

我检查了一遍(即使运行了这个命令),发现数据库根本没有数据。那么它怎么会出现主键不唯一的错误?

如果有关的话,UserProfile只是通过OneToOneField关系扩展了默认的User模型,就像这里提出的那样。

这是mydata.json包含的内容:

[
    {
        "model": "auth.user",
        "pk": 1,
        "fields": {
            "password": "pbkdf2_sha256..",
            "last_login": "2016-10-22T15:19:46.926Z",
            "is_superuser": true,
            "username": "thesuperuser",
            "first_name": "",
            "last_name": "",
            "email": "a@a.co",
            "is_staff": true,
            "is_active": true,
            "date_joined": "2016-10-22T14:48:27.394Z",
            "groups": [],
            "user_permissions": []
        }
    },
    {
        "model": "auth.user",
        "pk": 2,
        "fields": {
            "password": "pbkdf2_sha256..",
            "last_login": null,
            "is_superuser": false,
            "username": "user1",
            "first_name": "User",
            "last_name": "One",
            "email": "",
            "is_staff": false,
            "is_active": true,
            "date_joined": "2016-10-22T15:20:32Z",
            "groups": [],
            "user_permissions": []
        }
    },
    {
        "model": "auth.user",
        "pk": 4,
        "fields": {
            "password": "pbkdf2_sha256..",
            "last_login": null,
            "is_superuser": false,
            "username": "user3",
            "first_name": "User",
            "last_name": "Three",
            "email": "",
            "is_staff": false,
            "is_active": true,
            "date_joined": "2016-10-22T15:21:09Z",
            "groups": [],
            "user_permissions": []
        }
    },
    {
        "model": "auth.user",
        "pk": 3,
        "fields": {
            "password": "pbkdf2_sha256..",
            "last_login": null,
            "is_superuser": false,
            "username": "user2",
            "first_name": "User",
            "last_name": "Two",
            "email": "",
            "is_staff": false,
            "is_active": true,
            "date_joined": "2016-10-22T15:21:03Z",
            "groups": [],
            "user_permissions": []
        }
    },
    {
        "model": "myapp.userprofile",
        "pk": 1,
        "fields": {
            "user": 1,
            "money": 100
        }
    },
    {
        "model": "myapp.userprofile",
        "pk": 2,
        "fields": {
            "user": 2,
            "money": 100
        }
    },
    {
        "model": "myapp.userprofile",
        "pk": 3,
        "fields": {
            "user": 3,
            "money": 100
        }
    },
    {
        "model": "myapp.userprofile",
        "pk": 4,
        "fields": {
            "user": 4,
            "money": 100
        }
    }
]

感谢任何帮助,

7个回答

18

13

今天(2020年4月24日),我遇到了一个与Django 2.2类似的问题。

我的fixtures文件就像这样简单:

[
{
    "model": "contenttypes.contenttype",
    "pk": 1,
    "fields": {
        "app_label": "admin",
        "model": "logentry"
    }
},
{
    "model": "contenttypes.contenttype",
    "pk": 2,
    "fields": {
        "app_label": "auth",
        "model": "permission"
    }
}]

当我运行./manage.py loaddata initial_data.json时,出现以下提示:

django.db.utils.IntegrityError: 安装fixture '/home/user/reponame/projectname/initial_data.json'时出错:无法加载contenttypes.ContentType(pk=2):django_content_type.app_label和django_content_type.model的唯一约束失败。

为了使其正常工作,我只需将contenttypes.contenttype模型的pk更名为id。之后,迁移就像预期的那样工作。

./manage.py loaddata initial_data.json 
Installed 2 object(s) from 1 fixture(s)

修改后,我的initial_data.json文件如下:

[
{
    "model": "contenttypes.contenttype",
    "id": 1,
    "fields": {
        "app_label": "admin",
        "model": "logentry"
    }
},
{
    "model": "contenttypes.contenttype",
    "id": 2,
    "fields": {
        "app_label": "auth",
        "model": "permission"
    }
}]

值得一提的是,我的原始initial_dataj.json有许多其他模型,但仅将pk重命名为id(只针对contenttypes.contenttype)就解决了我的问题。


1
谢谢,这对我有效。之前我尝试将所有的pk更改为id,但是这会导致django.contrib.contenttypes.models.DoesNotExist: ContentType matching query does not exist. KeyError: 'content_type'的错误。 - chia yongkang
你的解决方案完美地运作了。但是这背后的原因是什么?这个解决方案有哪些缺点? - khadim husen
嗨@khadimhusen,我只是通过试错到达了这一点。 - Ruben Alves
这里也一样,这个解决方案可行。为什么他们不修复这个问题呢? - martintrapp
我不得不在contenttypes.contenttype和auth.permission中将"pk"更改为"id"。然后所有的固定装置都被加载了。 - undefined

7

3
我无法想象在进行数据库转储加载时,你会希望那些后置保存钩子运行的情况。 - Andy T

3

前往json文件并将每个'pk'更改为'id'。如果您使用vs code,只需选择1并按下cmd/ctrl + f2即可作为快捷方式。


1
对我来说不起作用,因为它会导致 content_type 错误。 - chia yongkang
对我来说,从*.sqlite3到MySQL完美运行!感谢@Zeyad!我的错误是: “无法加载contenttypes.ContentType(pk=3):(1062,“django_content_type.django_content_type_app_label_mod的键'django_content_type'中已存在重复条目'admin-logentry'” - pepefiestas

2
2023年了,我偶然发现了这个问题,并找到了原因。我在多个答案上进行了借鉴,这不是一条评论,而是为了解释我的需求。
默认情况下,Django会在每次添加新模型时运行一个信号。当你向应用程序添加新模型并运行迁移时,Django会在添加新模型实例的同时,在"ContentType"模型中创建一个条目。这意味着当你运行"dumpdata"然后再运行"loaddata"时,对于每个模型,一旦每个模型的第一条记录被添加到数据库中,Django立即创建一个带有对该模型的外键的"ContentType"。
一切都很顺利,直到加载JSON文件中的"ContentType"时。此时,数据库中当前存在的"ContentType"(由Django通过信号创建)与JSON文件中的记录发生冲突。
其他人指出的解决方案是从"dumpdata"命令中排除"ContentType"。我建议你还要从"admin"应用程序中排除所有内容,这基本上是日志条目。
接下来,在运行loaddata之前,你需要注释掉可能存在的任何信号。如果你不这样做,对于每个存在的信号,当loaddata加载一个具有信号的模型时,该信号将会运行并在数据库中创建记录,这将不可避免地导致尚未创建的json文件中的数据约束失败。
话虽如此,你最终的命令应该是:
python manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e admin -e auth.Permission --indent
 2 > dump.json

在你的Django应用中,你需要将涉及信号的所有代码注释掉。然后运行:
python manage.py loaddata dump.json

当您完成时(希望安装成功),您可以取消注释您的信号代码并且感到高兴!我希望这一切能够顺利进行。

0

在加载夹具时,请注释您的信号。


0
在导出和导入具有多对多关系的模型时遇到了相同的问题。这是因为我在导出时手动指定了多对多关系的中间模型,导致了唯一约束错误。
class MyModel(model.Model):
    
    groups = models.ManyToManyField(
        'myapp.mymodel',        
        
    )

你只需要执行dumpdata myapp.mymodel,而不是`dumpdata myapp.mymodel myapp.mymodel_groups"

否则,你的中间模型数据会被导出两次,从而引发唯一约束错误。
当你指定一个明确的中间模型时,它的行为是个好问题...我不知道也没有时间去测试 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接