Updated from Django 3.2 to 5.2, now I'm getting "Obj matching query does not exist"

I'm using Django in a non-Django project (Postgresql 17 under the hood) purely to make my unit tests easier. I've defined all my models like this:

class Bar(models.Model):
    internal_type = models.TextField(...)
    ...
   
    class Meta:
        managed = False
        db_table = 'myschema\".\"bar'      

class Foo(models.Model):
    ...
    bar = models.ForeignKey('Bar', models.DO_NOTHING, db_column='bar', blank=True, null=True)
 
   class Meta:
        managed = False
        db_table = 'myschema\".\"foo'      

This looks funky, but it was working perfectly fine on Django 3.2. It allowed me to write tests like this:

def test_foo(self):
    from app import models

    assert models.Foo.objects.count() == 0

    # self.cursor is a psycopg2 cursor
    # run_planner uses that cursor to create a bunch of Foo and related Bar objects
    run_planner(self.cursor)
    self.cursor.connection.commit()

    my_foos = models.Foo.objects.filter(bar__internal_type='special')
    
    assert my_foos.count() == 2 # this passes

    for m in my_foos:
        print(m.bar) # this raises DoesNotExist

This test passes with no issues on Django 3.2, but fails on that last line on 5.2. How can I work around this? It seems like Django is using some stricter transaction isolation behind the scenes? How can the .count() succeed, but the accessing it fail? Note that my_foos specifically asks for Foo objects with related Bar instances.

I've tried committing Django's cursor before, closing its connection and forcing it to re-open, etc. But nothing has worked.

Has my luck run out on this pattern of testing?

Вернуться на верх