Opened 8 years ago

Closed 8 years ago

#5662 closed (invalid)

get_or_create fails when there is a unique field and other values

Reported by: kenneth gonsalves <lawgon@…> Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Keywords: get_or_create
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

This is for svn head and postgresql backend. Assume a model like this:

class Word(models.Model):
    
    language=models.ForeignKey(Language)
    rootword=models.ForeignKey(Rootword,blank=True,null=True)
    word=models.CharField(_("Word"),maxlength=100,unique=True)
    english=models.CharField(_("English Meaning"),maxlength=500)

I want to dump values from some external source into this table using get_or_create. If the 'word' exists, the no action should be taken, otherwise the row has to be created. If i make my query like this:

a,b = Word.objects.get_or_create(word=wd, language=lng,rootword=rtwd, english=eng)

then unless *all* the fields match in the existing row, django assumes that the row does not exist and attempts to create the row which results in a duplicate key error in postgresql. As a result, the query has to be restricted to 'word' only, to avoid the duplicate key error. If the row containing 'word' is got, then the row has to be updated with the remaining values. If it is created - again it needs to be updated with the remaining values. This could be solved with an update_or_create query?

Change History (3)

comment:1 Changed 8 years ago by insin

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Isn't this why the defaults argument exists?

word, created = Word.objects.get_or_create(word=wd, defaults=dict(language=lng, rootword=rtwd, english=eng))

http://www.djangoproject.com/documentation/db-api/#get-or-create-kwargs

comment:2 Changed 8 years ago by Nis Jørgensen <nis@…>

Just for reference, the syntax for using the defaults argument would be

word, created = Word.objects.get_or_create(word=wd, defaults=dict('language':lng, 'rootword': rtwd, 'english':eng))

comment:3 Changed 8 years ago by ubernostrum

  • Resolution set to invalid
  • Status changed from new to closed

This is pretty much why defaults exists.

Note: See TracTickets for help on using tickets.
Back to Top