简体   繁体   中英

IntegrityError when loading auth.user and profile models in Django fixtures

I'm trying to create some fixtures to use for running tests in Django. Right now, I'm just dumping the appropriate models from my dev db and then loading those through the test. Here's the command I use to dump the fixtures:

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

Following this question and this one I've added flags for using natural keys and excluding content types. This doesn't help -- I get this error message:

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

I've check the fixture manually and there is only one entry for that user id. The Profile model is pretty standard, with some extra fields with personal information. It's linked to User in the model with the following:

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

post_save.connect(create_user_profile, sender=User)

In the name of completeness, here's what the fixtures look like:

{
    "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
    }
}

Any ideas? Is it because of the hook I use to link User and Profile?

I'm running Django 1.4 using the Enthought distro of Python 2.6, on Mac OS X (10.7.5).

This often happens with OneToOneFields() if you have:

Profile.user = models.OneToOneField(User) when django creates User records it automatically creates Profiles for these users (probably via post_save). So when loaddata starts to import Profiles, each User already has a profile and additional profiles break the constraint.

I had 2 models pointing to User via OneToOneField:

  • Profiles;
  • Calendar.

To fix the issue:

1) export auth.user into a separate auth_user.json;

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

2) export other models:

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

3) load User records: ./manage.py loaddata auth_user

4) open ./manage.py shell or shell_plus and delete all the Profiles and Calendar records:

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

5) load the rest of the records:

./manage.py loaddata other_models

I ran into this same problem. In my case I confirmed that the database row for User id=1 did not exist (via User.objects.all()).

In my case it turned out that I was loading two fixtures:

  • initial_preferences.json (custom user preferences)
  • initial_admin_user.json

The preferences fixture model has a ForeignKey reference to a User. If I load preferences first, I get the duplicate key error, even though there is still no User id=1.

Swapping the order to load the admin_user before preferences fixed the issue for moe.

So -- check to see if you have already created other model objects that have a reference to User id=1.

The problem is that you are trying to load fixtures into a DB that already contains those rows, so it' raising an IntegrityError . You could drop the tables before running the loaddata , but really the fixtures should only be used to initially populate the table.

Are you using Postgres database?

I ran into similar issue with loading fixtures and having Postgres as my database. Auto increment sequences were not set to the values they were supposed to be set.

This post helped me: https://www.vlent.nl/weblog/2011/05/06/integrityerror-duplicate-key-value-violates-unique-constraint/

This may not an offtopic, but since Google points here o similar problem with loading fixtures with eg. contenttypes.ContentType im inclined to help.

Use natural keys to avoid duplicate key value violations when data changes it's primary keys.

Add --natural-foreign option during dumpdata, eg.:

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

When using OneToOneField you probably have defined a post_save signal. So when the User is created the post_save signal that follows creates the Profile and when loaddata attempts to create the corresponding Profile it was already created by the post_save signal. The simplest thing to do is to comment out the post_save signals in your code just to execute loaddata .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM