Django loaddata ignore existing objects - python

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.

Related

How can I find a specific key from a python dict and then get a value from that key in Python

I have a python dictionary that looks something like this:
[
{
"timestamp": 1621559698154,
"user": {
"uri": "spotify:user:xxxxxxxxxxxxxxxxxxxx",
"name": "Panda",
"imageUrl": "https://i.scdn.co/image/ab67757000003b82b54c68ed19f1047912529ef4"
},
"track": {
"uri": "spotify:track:6SJSOont5dooK2IXQoolNQ",
"name": "Dirty",
"imageUrl": "http://i.scdn.co/image/ab67616d0000b273a36e3d46e406deebdd5eafb0",
"album": {
"uri": "spotify:album:0NMpswZbEcswI3OIe6ml3Y",
"name": "Dirty (Live)"
},
"artist": {
"uri": "spotify:artist:4ZgQDCtRqZlhLswVS6MHN4",
"name": "grandson"
},
"context": {
"uri": "spotify:artist:4ZgQDCtRqZlhLswVS6MHN4",
"name": "grandson",
"index": 0
}
}
},
{
"timestamp": 1621816159299,
"user": {
"uri": "spotify:user:xxxxxxxxxxxxxxxxxxxxxxxx",
"name": "maja",
"imageUrl": "https://i.scdn.co/image/ab67757000003b8286459151d5426f5a9e77cfee"
},
"track": {
"uri": "spotify:track:172rW45GEnGoJUuWfm1drt",
"name": "Your Best American Girl",
"imageUrl": "http://i.scdn.co/image/ab67616d0000b27351630f0f26aff5bbf9e10835",
"album": {
"uri": "spotify:album:16i5KnBjWgUtwOO7sVMnJB",
"name": "Puberty 2"
},
"artist": {
"uri": "spotify:artist:2uYWxilOVlUdk4oV9DvwqK",
"name": "Mitski"
},
"context": {
"uri": "spotify:playlist:0tol7yRYYfiPJ17BuJQKu2",
"name": "I Bet on Losing Dogs",
"index": 0
}
}
}
]
How can I get, for example, the group of values for user.name "Panda" and then get that specific "track" list? I can't parse through the list by index because the list order changes randomly.
If you are only looking for "Panda", then you can just loop over the list, check whether the name is "Panda", and then retrieve the track list accordingly.
Otherwise, that would be inefficient if you want to do that for many different users. I would first make a dict that maps user to its index in the list, and then use that for each user (I am assuming that the list does not get modified while you execute the code, although it can be modified between executions.)
user_to_id = {data[i]['user']['name']: i for i in range(len(data))} # {'Panda': 0, 'maja': 1}
def get_track(user):
return data[user_to_id[user]]['track']
print(get_track('maja'))
print(get_track('Panda'))
where data is the list you provided.
Or, perhaps just make a dictionary of tracks directly:
tracks = {item['user']['name']: item['track'] for item in data}
print(tracks['Panda'])
If you want to get list of tracks for user Panda:
tracks = [entry['track'] for entry in data if entry['user']['name'] == 'Panda']

How do i make this JSON structure work as intended?

I have some data from a project where the variables can change from motorcycle and car. I need to get the name out of them and that value is inside the variable.
This is not the data i will be using but it has the same structure, the "official" data is some persional information so i changed it to some random values. I can not change the structure of the JSON data since this is the way the serveradmins decided to structure it for some reason.
This is my python code:
import json
with open('exampleData.json') as j:
data = json.load(j)
name = 0
Vehicle = 0
for x in data:
print(data['persons'][x]['name'])
for i in data['persons'][x]['things']["Vehicles"]:
print(data['persons'][x]['things']['Vehicles'][i]['type']['name'])
print("\n")
This is my Json data i extracted from the file "ExampleData.json"(sorry for long but it is kinda complex and necessary to understand the problem):
{
"total": 2,
"persons": [
{
"name": "Sven Svensson",
"things": {
"House": "apartment",
"Vehicles": [
{
"id": "46",
"type": {
"name": "Kawasaki ER6N",
"type": "motorcyle"
},
"Motorcycle": {
"plate": "aaa111",
"fields": {
"brand": "Kawasaki",
"status": "in shop"
}
}
},
{
"id": "44",
"type": {
"name": "BMW m3",
"type": "Car"
},
"Car": {
"plate": "bbb222",
"fields": {
"brand": "BMW",
"status": "in garage"
}
}
}
]
}
},
{
"name": "Eric Vivian Matthews",
"things": {
"House": "House",
"Vehicles": [
{
"id": "44",
"type": {
"name": "Volvo XC90",
"type": "Car"
},
"Car": {
"plate": "bbb222",
"fields": {
"brand": "Volvo",
"status": "in garage"
}
}
}
]
}
}
]
}
I want it to print out something like this :
Sven Svensson
Bmw M3
Kawasaki ER6n
Eric Vivian Matthews
Volvo XC90
but i get this error:
print(data['persons'][x]['name'])
TypeError: list indices must be integers or slices, not str
Process finished with exit code 1
What you need is
for person in data["persons"]:
for vehicle in person["things"]["vehicles"]:
print(vehicle["type"]["name"])
type = vehicle["type"]["type"]
print(vehicle[type]["plate"])
Python for loop does not return the key but rather an object here:
for x in data:
Referencing an object as key
print(data['persons'][x]['name'])
Is causing the error
What you need is to use the returning json object and iterate over them like so:
for x in data['persons']:
print(x['name'])
for vehicle in x['things']['Vehicles']:
print(vehicle['type']['name'])
print('\n')

Django loaddata UNIQUE constraint failed

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.

Django: How to populate database from JSON

I would like to populate my model's DB from this JSON:
{
"pk": 1,
"model": "companies.Company",
"name": "Google",
"site": "google.com"
}
}{
"pk": 2,
"model": "companies.Company",
"fields": {
"name": "Zoho",
"site": "zoho.com",
}
}{
"pk": 3,
"model": "companies.Company",
"fields": {
"name": "Digg",
"site": "digg.com",
}
}{
I've made my JSON like how the documentation describes but I'm not sure what to do from here!
If anyone knows what I have to do from here I would love some help! Happy to answer any questions about this!
EDIT:
I was told to run
./manage.py loaddata companies.json
When I ran that I got:
' django.core.serializers.base.DeserializationError: Problem
installing fixture 'PATH_TO_FILE/companies/fixtures/companies.json':
Extra data: line 21 column 2 - line 5586860 column 6 (char 909 -
249730297)'
"line 21 column 2 - line 5586860 column 6 (char 909 -249730297)" Being the last character in the file. I also tried removing one whole entry to the model(to eliminate that maybe the last entry was messed up), but I again got the same error with the error referring to the last character in the file again.
EDIT 2
Lines 20, and 21 are simply where the first entry ends and the second one begins(Line 20 is the last line in the example shown in the example above):
Line 20: " }"
Line 21: "}{"
P.S. The reason why it's line 20 and 21 is that there are actually more fields than; name, and site, the one's shown in the question.
That's not valid JSON; you can't have a close brace immediately followed by an open brace. You need a comma between them, but in order for that to be valid you'd need the whole file to be enclosed in [...].
With that file inside your "companies/fixtures" directory, you should just have to run
./manage.py loaddata your-fixture-filename.json
And fixed JSON from your example:
[
{
"pk": 1,
"model": "companies.Company",
"fields": {
"name": "Google",
"site": "google.com"
}
},
{
"pk": 2,
"model": "companies.Company",
"fields": {
"name": "Zoho",
"site": "zoho.com"
}
},
{
"pk": 3,
"model": "companies.Company",
"fields": {
"name": "Digg",
"site": "digg.com"
}
}
]

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