Запрос по внешнему ключу Django возвращает записи, которых нет в базе данных

У меня возникла странная ситуация, когда Django, похоже, выдает мне записи, которых на самом деле не существует в базе данных, при запросе через related_name по внешнему ключу. Вот упрощенный пример:

Допустим, у меня есть модель Person и модель Pet, где у каждого питомца есть владелец, который является внешним ключом на Person:

class Pet(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name =models.CharField(max_length=50, null=False, db_index=True)
    owner = models.ForeignKey("Person", null=False, related_name="pets", on_delete=models.CASCADE)
    relationship = models.IntegerField(null=False, choices=PetRelationship.choices(), db_index=True)

Теперь у меня есть следующая функция, которая извлекает домашних животных человека:

def pet_tester(person):
    for pet in person.pets.filter(relationship=PetRelationship.FRIENDLY):
        pet_id = pet.id
        LOGGER.info(f"*************** pet.id = {pet_id}")
        LOGGER.info(f"******* Pet exists? = {Pet.objects.filter(id=pet_id).exists()}")
        ...

Обратите внимание, что это НЕ "минимальный воспроизводимый пример". Я могу воспроизвести его только в своем гораздо более крупном приложении.

По какой-то причине (в реальном приложении) запрос "exists" возвращается как False. Вывод выглядит следующим образом:

*************** pet.id = 123e4567-e89b-12d3-a456-426614174000
******* Pet exists? = False

Если я делаю запрос к реальной базе данных (Postgresql) напрямую (вне Django), то ID животного, конечно же, НЕ существует. Однако запрос person.pets.filter возвращает его точно так же.

Я не понимаю, как такое вообще возможно. Он ДЕЙСТВИТЕЛЬНО извлекает питомца из базы данных (или так кажется - у него даже есть UUID), но когда я тут же пытаюсь запросить его обратно, его там нет.

Похоже, что результаты "фильтра" Django каким-то образом не согласуются с базой данных, но я не знаю почему. Это очень воспроизводимо в моем приложении (это происходит каждый раз, последовательно). Это не похоже на повреждение базы данных, так как это постоянно происходит даже на совершенно новых машинах, со свежеустановленным приложением и базой данных.

Я знаю, что вы не знаете, что еще делает мое приложение. Я, конечно, не могу выложить весь исходный код, но могу заверить вас, что начало фактической функции практически дословно повторяет функцию pet_tester, приведенную выше. Я изменил только имена классов/полей. В самом приложении нет лишних строк между строкой "for" и тремя строками ниже.

Я в основном ищу идеи о том, как это может произойти, и что искать в другом коде приложения.

Оказалось, что существует другой сервис, который удаляет "домашних животных" из базы данных. В Django должно быть какое-то кэширование, и поскольку удаление произошло вне Django, Django не аннулировал свой кэш "person.pets".

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