Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#28253 closed Bug (invalid)

Integrity error in get_or_create

Reported by: Anuranjit maindola Owned by: Anuranjit maindola
Component: Database layer (models, ORM) Version: 1.11
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Tim Graham)

I came across an issue. Consider a code example below

class Config(models.Model):
    key = models.CharField(max_length=100)
    value = models.CharField(max_length=100)
    def save(self, *args, **kwargs):
         super(Config, self).save(*args, **kwargs)
         super(Config, self).save(*args, **kwargs)

Now if for the Above model I do

params = {"key":"1", "value": "2"}
obj, created = Config.objects.get_or_create(**params)

I get an Integrity Error for Primary Key i.e. the database id field.

The issue as i understood comes because Django tries to insert again with duplicate Primary key. In get_or_create the create method is called with force_insert=True and a particular check in _save_table fails (line number 897) . (If this check passes django is supposed to do an update).

    # If possible, try an UPDATE. If that doesn't update anything, do an INSERT.
    if pk_set and not force_insert:

Change History (4)

comment:1 by Tim Graham, 7 years ago

Description: modified (diff)

What's the reason for calling super().save() twice?

comment:2 by Tim Graham, 7 years ago

Resolution: invalid
Status: assignedclosed

Absent a justification for the double save, this looks like invalid usage rather than a bug in Django.

comment:3 by Anuranjit maindola, 7 years ago

@Tim Graham .
Doing any number of saves should be fine.
Can you elaborate on why is this is not a valid issue?

comment:4 by Marten Kenbeek, 7 years ago

The issue is that you save twice with force_insert=True, without changing the value of the primary key. If you want to update the object after the first save, you need to strip the force_insert argument from **kwargs.

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