patternpythondjangoMinor
Unpacking tuple from Django's get_or_create function
Viewed 0 times
djangofunctiontuplefromunpackingget_or_create
Problem
Django's
But this doesn't look particularly elegant. Is there a better way to do this, possibly avoiding the double loop?
get_or_create function returns 2 values: the object and a boolean whether it was freshly created or not. I'm only really interested in the object it returns and this is how I'm doing it.keywords = [element for (element, _) in [Keyword.objects.get_or_create(keyword=key) for key in keywords]]But this doesn't look particularly elegant. Is there a better way to do this, possibly avoiding the double loop?
Solution
I'd say this is a good example on how to not use DB.
The problem here is that for each keyword you will call a DB instead of perform this as a single call, so if you list of keywords is 1000 items then you will do 1000 calls to DB.
You can avoid this by splitting your call to:
Note: If you are running on django 1.10+ and using Postgres then step 4 is not needed, since bulk_create will populate your keyword objects with PKs, otherwise you should do step 4
The problem here is that for each keyword you will call a DB instead of perform this as a single call, so if you list of keywords is 1000 items then you will do 1000 calls to DB.
You can avoid this by splitting your call to:
- Get existing keywords
existing_keywords = Keyword.objects.filter(keyword__in=keywords).values_list('keyword', flat=True)- Get list of not existing keywords
keywords = set(keywords)
not_existing_keywords = keywords.difference(existing_keywords)- Create objects with no existing keywords
Keyword.objects.bulk_create(Keyword(keyword=key) for key in keyword))- Now finally query your data from DB
keywords_qs = Keyword.objects.filter(keyword__in=keywords)Note: If you are running on django 1.10+ and using Postgres then step 4 is not needed, since bulk_create will populate your keyword objects with PKs, otherwise you should do step 4
Code Snippets
existing_keywords = Keyword.objects.filter(keyword__in=keywords).values_list('keyword', flat=True)keywords = set(keywords)
not_existing_keywords = keywords.difference(existing_keywords)Keyword.objects.bulk_create(Keyword(keyword=key) for key in keyword))keywords_qs = Keyword.objects.filter(keyword__in=keywords)Context
StackExchange Code Review Q#153629, answer score: 8
Revisions (0)
No revisions yet.