【问题标题】:IntegrityError when loading auth.user and profile models in Django fixtures在 Django 固定装置中加载 auth.user 和配置文件模型时出现 IntegrityError
【发布时间】:2013-04-02 22:54:41
【问题描述】:

我正在尝试创建一些用于在 Django 中运行测试的装置。现在,我只是从我的开发数据库中转储适当的模型,然后通过测试加载它们。这是我用来转储灯具的命令:

python manage.py dumpdata accounts.Profile auth.User -n auth.User --indent 4 -e contenttypes > path/to/fixture.json

this questionthis one 之后,我添加了使用自然键和排除内容类型的标志。这无济于事——我收到以下错误消息:

IntegrityError: Could not load accounts.Profile(pk=1): duplicate key value violates unique constraint "accounts_profile_user_id_key"
DETAIL:  Key (user_id)=(1) already exists

我已经手动检查了灯具,并且该用户 ID 只有一个条目。 Profile 模型非常标准,带有一些带有个人信息的额外字段。它通过以下方式链接到模型中的用户:

def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

post_save.connect(create_user_profile, sender=User)

以完整性的名义,以下是固定装置的外观:

{
    "pk": 1, 
    "model": "auth.user", 
    "fields": {
        "username": "unique_username", 
        "first_name": "", 
        "last_name": "", 
        "is_active": true, 
        "is_superuser": true, 
        "is_staff": true, 
        "last_login": "2013-03-31T23:19:44.391", 
        "groups": [], 
        "user_permissions": [], 
        "password": "secret",
        "email": "email", 
        "date_joined": "2013-03-13T21:30:39.225"
    }
},
{
    "pk": 1, 
    "model": "accounts.profile", 
    "fields": {
        "status": "active", 
        "first_name": "John", 
        "last_name": "Smith", 
        "middle_name": null, 
        "headline": "Something very cool", 
        "user": [
            "unique_username"
        ], 
        "location": null
    }
}

有什么想法吗?是因为我用来链接用户和个人资料的钩子吗?

我在 Mac OS X (10.7.5) 上使用 Python 2.6 的 Enthought 发行版运行 Django 1.4。

【问题讨论】:

    标签: python django fixtures


    【解决方案1】:

    如果您有以下情况,OneToOneFields() 经常会发生这种情况:

    Profile.user = models.OneToOneField(User) 当 django 创建用户记录时,它会自动为这些用户创建配置文件(可能通过 post_save)。所以当 loaddata 开始导入 Profiles 时,每个 User 已经有一个 Profile 并且额外的 Profile 打破了约束。

    我有 2 个模型通过 OneToOneField 指向用户:

    • 个人资料;
    • 日历。

    解决问题:

    1) 将 auth.user 导出为单独的 auth_user.json;

    ./manage.py dumpdata --indent=4 auth.user > auth_user.json
    

    2) 导出其他模型:

    ./manage.py dumpdata --indent=4 -e sessions -e admin -e contenttypes -e auth.Permission --natural-foreign > other_models.json
    

    3) 加载用户记录: ./manage.py 加载数据 auth_user

    4) 打开./manage.py shellshell_plus 并删除所有配置文件和日历记录:

    Profiles.objects.all().delete()
    Profiles.objects.all().count()
    Calendar.objects.all().delete()
    Calendar.objects.all().count()
    

    5) 加载其余记录:

    ./manage.py loaddata other_models
    

    【讨论】:

    • 这让我找到了解决问题的大部分方法,但我最终只是注释掉了在添加或保存用户时自动创建关联 Profile 的代码,运行 loaddata 命令,然后取消注释。谢谢!
    【解决方案2】:

    我遇到了同样的问题。在我的情况下,我确认用户 id=1 的数据库行不存在(通过 User.objects.all())。

    在我的例子中,我加载了两个固定装置:

    • initial_preferences.json(自定义用户首选项)
    • initial_admin_user.json

    preferences 夹具模型有一个对 User 的 ForeignKey 引用。如果我先加载首选项,我会收到重复键错误,即使仍然没有 User id=1。

    在首选项修复 moe 的问题之前交换顺序以加载 admin_user。

    所以 -- 检查您是否已经创建了引用 User id=1 的其他模型对象。

    【讨论】:

      【解决方案3】:

      问题是您试图将固定装置加载到已经包含这些行的数据库中,因此它会引发IntegrityError。您可以在运行 loaddata 之前删除这些表,但实际上这些装置应该只用于最初填充表。

      【讨论】:

      • Django 测试数据库是否已经包含所有数据?我认为,可能是错误的,测试数据库中的唯一数据就是我包含在夹具中的数据。
      【解决方案4】:

      你在使用 Postgres 数据库吗?

      我在加载固定装置并将 Postgres 作为我的数据库时遇到了类似的问题。自动增量序列未设置为应设置的值。

      这篇文章帮助了我:https://www.vlent.nl/weblog/2011/05/06/integrityerror-duplicate-key-value-violates-unique-constraint/

      【讨论】:

        【解决方案5】:

        这可能不是题外话,但由于谷歌在这里指出了加载固定装置的类似问题,例如。 contenttypes.ContentType我愿意帮忙。

        使用natural keys 避免在数据更改其主键时重复键值违规。

        在转储数据期间添加--natural-foreign选项,例如:

        $ python manage.py dumpdata --natural-foreign contenttypes auth.Permission auth.Group
        

        【讨论】:

          【解决方案6】:

          使用OneToOneField 时,您可能已经定义了post_save 信号。因此,当创建用户时,随后的post_save 信号会创建配置文件,而当loaddata 尝试创建相应的配置文件时,它已经由post_save 信号创建。最简单的做法是注释掉代码中的post_save 信号,以便执行loaddata

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-10-25
            • 1970-01-01
            • 2013-11-20
            • 2019-12-09
            • 1970-01-01
            • 1970-01-01
            • 2011-12-14
            • 1970-01-01
            相关资源
            最近更新 更多