get_or_create created 2 instances [Sloppy Development]

I am a woman enough to talk about this. I usually don’t let these things happen, but this is such a small thing that let me down on a really high amount of requests.

The statistics of an API I was using showed that at 00:00 UTC we stopped using it altogether.

So, the culprit is the simplest model ever:

class Date(models.Model):
    date = DateField()

And I only ever created it (or altered) like this:

    date, cr = Date.objects.get_or_create(
        day=f'{this_moment.year}-{this_moment.month}-{this_moment.day}'

As it always happens, 4am Sunday it well went to hell – Django create two instances of ‘2021-08-15’.

Eventually every requests that had this line in it just crashed.

Why did this happen? Well, apparently two instances are not supposed to be made.

My friends and I came to a conclusion that with a very high amount of requests Django missed that tiny bit of time between executing get_or_create method and actually writing an instance to PostgreSQL.

Well good thing - I went to bed late, and my team woke me up much earlier than I would wake up.

What is he solution? If the field is meant to be unique, make it unique:

class Date(models.Model):
    date = DateField(unique=True)

How to access Model’s pk/id when you create an instance in Django

If you need to modify instance fields depending on the instance’s pk or id, hop on.

When you create an instance, before it is saved, you can’t have pk or id as it is not yet created.

    def save(self, *args, **kwargs):
        # self.pk == None
        # self.id == None
        super().save(*args, **kwargs)
        # self.pk != None
        # self.id != None        

If you have a property that somehow depends on the value of self.pk or self.id and you want to have it saved on creating, you have two options.

Read More »