Как использовать Django ORM для поиска висячих записей?
Как можно использовать Django ORM для написания чего-то похожего на следующий SQL:
SELECT * FROM entities
WHERE NOT EXISTS (SELECT 1 FROM apples WHERE apples.entity_id = entities.id)
AND NOT EXISTS (SELECT 1 FROM oranges WHERE oranges.entity_id = entities.id)
AND NOT EXISTS (SELECT 1 FROM bananas WHERE bananas.entity_id = entities.id)
У меня есть несколько мета-таблиц, которые ссылаются на фактическую запись с деталями, но возможно, что у этих записей нет ссылок, и в этом случае они "болтаются".
Проблема в том, что имеется более 100 миллионов записей, поэтому простой exclude
с использованием in
фильтра не работает:
Entity.objects.exclude(userid__in=Apple.objects.all().values_list('entity_id'))
SQL-оператор с использованием NOT EXISTS
, с другой стороны, выполняется молниеносно.
В настоящее время я работаю на Django 2.2 (с планами обновления до 4.x в течение года).
Вы можете .filter(…)
[Django-doc] с:
Entity.objects.filter(apple=None, orange=None, bana=None)
Это сделает LEFT OUTER JOIN
на таблицах для моделей Apple
, Orange
и Banana
, а затем проверит, являются ли они None
/NULL
.
It will work with the value related_query_name=…
parameter [Django-doc] for the ForeignKey
s from Apple
, Orange
and Banana
to Entity
. If that one is not specified, it will use the related_name=…
parameter [Django-doc] instead, and if that is not specified either, it uses the name of the model in lowercase, so here apple
, orange
and banana
.