HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythondjangoMinor

Unpacking tuple from Django's get_or_create function

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
djangofunctiontuplefromunpackingget_or_create

Problem

Django's 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:

  1. Get existing keywords



existing_keywords = Keyword.objects.filter(keyword__in=keywords).values_list('keyword', flat=True)


  1. Get list of not existing keywords



keywords = set(keywords)
not_existing_keywords = keywords.difference(existing_keywords)


  1. Create objects with no existing keywords



Keyword.objects.bulk_create(Keyword(keyword=key) for key in keyword))


  1. 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.