Запрос по внешнему ключу 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".