Reputation: 3726
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).
Upvotes: 6
Views: 4830
Reputation: 31
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
.
Upvotes: 3
Reputation: 5191
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:
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
Upvotes: 11
Reputation: 19040
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
Upvotes: 2
Reputation: 769
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/
Upvotes: 0
Reputation: 11
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:
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.
Upvotes: 1
Reputation: 53998
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.
Upvotes: 0