get_or_create UNIQUE constraint error

Given the following Model:

class Model1(models.Model):
    m2mrelation = models.ManyToManyField('Model2', related_name='model2')
    field1 = models.CharField(max_length=14)
    data1 = models.FloatField()
    data2 = models.FloatField()
    data3 = models.FloatField()
    data4 = models.FloatField()
    data5 = models.FloatField()
    field2 = models.CharField(max_length=10)
    field3 = models.CharField(max_length=20)

    class Meta:
        indexes = [
            models.Index(fields=['field1', 'field2', 'field3']),
        ]

        unique_together = ['field1', 'field2', 'field3']

I’m trying to use the “get_or_create()” method to get or create a new Model1 inside a Model2 method:

for data in objects:
     object, created = self.model1.get_or_create(
          field1=field1,
          field2=field2,
          field3=field3,
          defaults={
                    'data1': float(data[1]),
                    'data2': float(data[2]),
                    'data3': float(data[3]),
                    'data4': float(data[4]),
                    'data5': float(data[5])
          }
     )

     if not object.m2mrelation.filter(id=self.id).exists():
          object.m2mrelation.add(self)

When I’m trying to create new objects, I’m getting the IntegrityError: UNIQUE constraint failed in the get_or_create method.

Am I missing something?

I’d assume that one of the times you call that method, the values of at least two of field1, field2, and field3 are the same.

Hi @philgyford thank you for the answer.

Doesn’t unique_together only check if all three constraints are violated together? So, if only two of them are the same, shouldn’t it pass the check?

Oh yes, sorry, I think you’re right. In which case I’d assume that all three are the same.

But if all of them already exist together, doesn’t get_or_create return the existing instance instead of trying to create a new one?

Oh, again, yes, you’re right. I’ve been trying to do too many things at once, so I’ll butt out of this :slight_smile:

One thing that might help someone else help you is: can you clarify what you mean by “I’m trying to use the “get_or_create()” method to get or create a new Model1 inside a Model2 method” ?

The code you showed isn’t in a method. Can you give a slightly fuller example of what you’re actually doing?

Hi @philgyford , I found the problem!

The issue was here: object, created = self.model1.get_or_create. I was using self.model1 instead of model1.objects.get_or_create, so Django wasn’t searching for the record within the entire model1 table.

Now it’s working! Thanks for your time!

1 Like