1

I am using Django 3.2.

Backend database used for testing: sqlite3

I have a model Foo:

class Foo(models.Model):
    # some fields ...
    some_count = models.IntegerField()

    class Meta:
        models.constraints = [
            models.CheckConstraint(
                check = ~models.Q(some_count=0), 
                name = 'check_some_count',
            ),
        ]            

  

I also have a unit test like this:

def test_Foo_some_count_field_zero_value(self):
    # Wrap up the db error in a transaction, so it doesn't get percolated up the stack
    with transaction.atomic():
        with self.assertRaises(IntegrityError) as context:
            baker.make(Foo, some_count=0)

When my unit tests are run, it fails at the test above, with the error message:

    baker.make(Foo, some_count=0)
AssertionError: IntegrityError not raised

I then changed the CheckConstraint attribute above to:

    class Meta:
        models.constraints = [
            models.CheckConstraint(
                check = models.Q(some_count__lt=0) | models.Q(some_count__gt=0), 
                name = 'check_some_count',
            ),
        ]   

The test still failed, with the same error message. I then tried this to check if constraints were being enforced at all:

def test_Foo_some_count_field_zero_value(self):
    foo = baker.make(Foo, some_count=0)
    self.assertEqual(foo.some_count, 0)

To my utter dismay, the test passed - clearly showing that the constraint check was being ignored. I've done a quick lookup online to see if this is a known issue with sqlite3, but I haven't picked up anything on my radar yet - so why is the constraint check being ignored - and how do I fix it (without overriding models.Model.clean() ) ?

Homunculus Reticulli
  • 65,167
  • 81
  • 216
  • 341

1 Answers1

0

Maybe you should try constraints not models.constraints

    class Meta:
        constraints = [
            ...
        ]
Artem Dumanov
  • 381
  • 2
  • 21