Django loaddata UNIQUE constraint failed - python

I'm running python manage.py loaddata 'path/to/mydata.json' with an empty database (User and UserProfile tables are created but not populated), however, I'm getting the following error:
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
I checked (even after running this command) and the database is not populated at all. So how can it be giving an error that the pk is not unique?
If relevant, UserProfile just extends the default User model with a OneToOneField relation, as proposed here.
Here is what mydata.json contains:
[
{
"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
}
}
]
Thanks for any help,

Exclude ContentType and Auth Permissions objects when creating a db dump.
python manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 2 > dump.json
After that you should be able to run the command without any issue
python manage.py loaddata dump.json
Credit to
https://www.coderedcorp.com/blog/how-to-dump-your-django-database-and-load-it-into-/
for saving my day

Today (24th, April, 2020) I had a similar problem with Django 2.2
My fixtures file was as simple as this:
[
{
"model": "contenttypes.contenttype",
"pk": 1,
"fields": {
"app_label": "admin",
"model": "logentry"
}
},
{
"model": "contenttypes.contenttype",
"pk": 2,
"fields": {
"app_label": "auth",
"model": "permission"
}
}]
When I ran ./manage.py loaddata initial_data.json, I got:
django.db.utils.IntegrityError: Problem installing fixture '/home/user/reponame/projectname/initial_data.json': Could not load contenttypes.ContentType(pk=2): UNIQUE constraint failed: django_content_type.app_label, django_content_type.model
What I did to make it work was just rename the pk to id for the contenttypes.contenttype model. After that, the migration worked as expected.
./manage.py loaddata initial_data.json
Installed 2 object(s) from 1 fixture(s)
After the change, my initial_data.json file was:
[
{
"model": "contenttypes.contenttype",
"id": 1,
"fields": {
"app_label": "admin",
"model": "logentry"
}
},
{
"model": "contenttypes.contenttype",
"id": 2,
"fields": {
"app_label": "auth",
"model": "permission"
}
}]
It is worth mentioning that my original initial_dataj.json has many other models, but renaming pk to id only for the contenttypes.contenttype solved my problem.

I had a similar problem. Inspired by this post:
https://github.com/yourlabs/django-cities-light/issues/89 (See 'how to fix it')
before running the loaddata command, I commented the receiver signal decorator before the 'saving function', and it worked.

go the the json file and change evey single 'pk' to 'id'
if you use vs code you can just select 1 and press cmd/ctrl + f2 as a shortcut

Had the same problem while exporting and importing a model with a ManyToMany relation. This was, because I manually speficied the ManyToMany through model while exporting, what caused an unique constraint error.
class MyModel(model.Model):
groups = models.ManyToManyField(
'myapp.mymodel',
)
You only need to execute dumpdata myapp.mymodel, not `dumpdata myapp.mymodel myapp.mymodel_groups"
Otherwise, your through model data is in the export twice, and causes a unique constraint error.
It`s a good question how this behaves, when you specify an explicit through model...i don't know and have no time to test :)

Comment your signals while loading the fixture.

Related

Django Annotate Getting full list of Users and add flag. Removing users that appear as duplicate

Been stuck on this for a good few hours now, I'm sure its something simple im missing.
I want to get full list of Users, but with 'participant' flag added if they are in Project.participants(m2m). That part works!
Model:
class Project(TimeStampedModel, Slugify):
...
participants = models.ManyToManyField(User, blank=True, related_name='%(app_label)s_%(class)s_participants')
...
User.objects.queryset.annotate(
participant=Case(
When(
projects_project_participants__in=project_id,
then=Value(project_id)
),
output_field=IntegerField()
)
).order_by('id')
I can get the right results if I filter out the rest. But I want to keep full queryset with both true and false.
The issue is, if a User is part of 5 groups for instance, then I have both True and False records in data set. (i have 2 results as i have set distinct, but left with a true and false version from different projects).
Any ideas of best approach or a simple filter I am missing.
Result I get:
"data": [
{
"type": "User",
"id": "1",
"attributes": {
"first_name": "Joe",
"last_name": "Blogs",
"is_active": true,
"participant": 2 ------ (its in project)
}
},
{
"type": "User",
"id": "1",
"attributes": {
"first_name": "Joe",
"last_name": "Bloggs",
"is_active": true,
"participant": null. ----- (this one should not be here)
}
},
{
"type": "User",
"id": "2",
"attributes": {
"first_name": "Barry",
"last_name": "Davis",
"is_active": false,
"participant": 2 ------ (its in project)
}
},
{
"type": "User",
"id": "3",
"attributes": {
"first_name": "Betty",
"last_name": "Davis",
"is_active": false,
"participant": null ------ (not in project but i still want this result)
}
},
]
You should be able to use Exists:
from django.db.models import Exists, OuterRef
User.objects.annotate(
in_project=Exists(
Project.objects.filter(
id=project_id,
participants=OuterRef('pk'),
)
)
)

Django loaddata ignore existing objects

I have a fixture with list of entries. eg:
[
{
"fields": {
"currency": 1,
"price": "99.99",
"product_variant": 1
},
"model": "products.productprice",
"pk": 1
},
{
"fields": {
"currency": 2,
"price": "139.99",
"product_variant": 1
},
"model": "products.productprice",
"pk": 2
}
]
This is only initial data for each entry (The price might change). I would like to be able to add another entry to that fixture and load it with loaddata but without updating entries that already exist in the database.
Is there any way to do that? Something like --ignorenonexistent but for existing entries.
If you keep pk in the json like that, you will always overwrite the first two records in product.productprice.
I would use "pk: null".
This way, you will always create new record with every load.
So if you want to create a new price:
[
{
"fields": {
"currency": 1,
"price": "99.99",
"product_variant": 1
},
"model": "products.productprice",
"pk": 1
},
{
"fields": {
"currency": 2,
"price": "139.99",
"product_variant": 1
},
"model": "products.productprice",
"pk": 2
},
{
"fields": {
"currency": 4,
"price": "9.99",
"product_variant": 1
},
"model": "products.productprice",
"pk": null
}
]
The first two records are always be the same, but if you already added a third one ( pk:3 ) with the last section you will create a new productprice with pk: 4.
BTW: if your currency field is an other primary key(with autoincrement), you can put "null" there too, a new primary key will be generated.

django unit testing with fixtures - object matching query does not exist

I am trying to set up unit testing in django using fixtures.
I can successfully load my fixtures, but when I attempt to retrieve data from them I get the error:
DoesNotExist: BlogIndexPage matching query does not exist.
Here is my code for the test (I'm using the Wagtail CMS, which extends unittest with a few additional methods):
class BlogTests(WagtailPageTests):
fixtures = ['demosite.json']
def test_can_create_blog_entry(self):
blog_index_page = BlogIndexPage.objects.get(pk=5)
self.assertCanCreate(blog_index_page, BlogPage, {
'title': 'Post 2',
'date': '2017-10-11',
'intro': 'Post 2',
'body': '<p>Test Post</p>'
})
And this is my fixture:
[
{
"pk": 1,
"model": "wagtailcore.page",
"fields": {
"title": "Root",
"draft_title": "Root",
"numchild": 1,
"show_in_menus": false,
"live": true,
"seo_title": "",
"depth": 1,
"search_description": "",
"content_type": [
"wagtailcore",
"page"
],
"has_unpublished_changes": false,
"owner": null,
"path": "0001",
"url_path": "/",
"slug": "root"
}
},
{
"pk": 2,
"model": "wagtailcore.page",
"fields": {
"title": "Home page",
"draft_title": "Home page",
"numchild": 5,
"show_in_menus": true,
"live": true,
"seo_title": "",
"depth": 2,
"search_description": "",
"content_type": [
"home",
"homepage"
],
"has_unpublished_changes": false,
"owner": null,
"path": "00010002",
"url_path": "/home-page/",
"slug": "home-page"
}
},
{
"pk": 5,
"model": "wagtailcore.page",
"fields": {
"title": "Blog index",
"draft_title": "Blog index",
"numchild": 3,
"show_in_menus": true,
"live": true,
"seo_title": "",
"depth": 3,
"search_description": "",
"content_type": [
"blog",
"blogindexpage"
],
"has_unpublished_changes": false,
"owner": null,
"path": "000100020002",
"url_path": "/blog/",
"slug": "blog"
}
},
{
"pk": 16,
"model": "wagtailcore.page",
"fields": {
"title": "Blog post",
"draft_title": "Blog post",
"numchild": 0,
"show_in_menus": false,
"live": true,
"seo_title": "",
"depth": 4,
"search_description": "The origin of the genus appears to be in the general area of Eastern Siberia/Mongolia. Wagtails spread rapidly across Eurasia and dispersed to Africa in the Zanclean (Early Pliocene) where the sub-Saharan lineage was later isolated. The African Pied Wagtail (and possibly the Mekong Wagtail) diverged prior to the massive radiation of the white-bellied black-throated and most yellow-bellied forms, all of which took place during the late Piacenzian (early Late Pliocene), c. 3 mya.",
"content_type": [
"blog",
"blogpage"
],
"has_unpublished_changes": false,
"owner": null,
"path": "0001000200020001",
"url_path": "/home-page/blog-index/blog-post/",
"slug": "blog-post"
}
}
]
So basically I just want to grab that blog index page, and test whether I can create a blogpage (blog post) underneath it. What am I doing wrong?
Your fixture needs to include records for "model": "blog.blogindexpage" as well as "model": "wagtailcore.page", with matching pk values. This is because Wagtail uses multi-table inheritance to represent pages: the data for a page is split across the wagtailcore_page table (which contains the core fields common to all page types, such as title) and another table such as blog_blogindexpage for each page model, containing the additional fields defined for that specific model. Without records in both tables, a lookup on BlogIndexPage will return no results, causing the DoesNotExist error above.
You can run ./manage.py dumpdata --indent 4 to get a dump of your development database in the JSON format used by fixtures; depending on the needs of your tests, you can either use this directly (./manage.py dumpdata --indent 4 > blog/fixtures/demosite.json) or use it as a guide for writing your own fixture manually.

invalid model identifier: 'sites.site'

When I try to run manage.py syncdb, I get this error:
django.core.serializers.base.DeserializationError: Problem installing fixture '/Users/cbplusd/repos/wibo1/fixtures/initial_data.json': Invalid model identifier: 'sites.site'
My installed_apps in my settings.py no longer contains django.contrib.sites, and my .json file looks like this:
[
{
"pk": 1,
"model": "sites.site",
"fields": {
"domain": "localhost:8000",
"name": "wibo"
}
},
{
"pk": 2,
"model": "sites.site",
"fields": {
"domain": "example.com",
"name": "wibo"
}
}
]
Does anyone know what I'm doing wrong?

How to real named auth_group_permissions in Django?

I want to create fixtures for auth_group_permissions table, but how named it model?
'auth.group.permissions' is not right.
[
{
"model": "auth.group",
"pk": 1,
"fields": {"name": "manager"}
},
{
"model": "auth.group",
"pk": 2,
"fields": {"name": "executive"}
},
{
"model": "auth.group",
"pk": 3,
"fields": {"name": "ordinar"}
},
{
"model": "auth.group.permissions",
"pk": 1,
"fields": {
"group_id": 1,
"permission_id": 7
}
}
]
You can define them in the group as related field
"model": "auth.group",
"fields": {
"name": "foo",
"permissions": [
...
]
There is no model named group.permissions in auth app. But class Group has many-to-many field permissions, so you should use it for your purpose.
Try this fixture:
{
"model": "auth.group",
"pk": 1,
"fields": {
"name": "manager",
"permissions" : [7]
}
}

Categories

Resources