Django ORM определяет приоритет столбца с (почти) дублирующимися данными
Базовая таблица БД является:
class ModelA(models.Model):
type_of_input = models.CharField(max_length=10) # say "USER" or "SOURCE"
date = models.DateField()
volume = models.IntegerField()
object_referenced = Foreign_key...
Проблема
Иногда мы имеем две дублирующиеся записи в ModelA - это означает, что два значения для date
и object_referenced
одинаковые, но значения для type_of_input
разные. Это означает, что нам нужно установить приоритет одного значения ("SOURCE") для type_of_input
над другим ("USER"), чтобы убедиться в правильности значения volume
(поскольку "USER" иногда может быть неверным).
Мы всегда получаем данные от (иногда ненадежного) "USER" type_of_input
, но только иногда получаем данные от (всегда правильного) "SOURCE" type_of_input
. Поэтому, когда присутствует тип входного значения "ИСТОЧНИК", нам нужно вернуть только строку "ИСТОЧНИК", а не строку "ПОЛЬЗОВАТЕЛЬ"
Вопрос
Как мы можем сделать это с помощью Django ORM, чтобы получить только одну строку на дату (приоритет значения "SOURCE" для type_of_input
?
Вам нужно использовать order_by()
, чтобы поставить "SOURCE" перед "USER", а затем взять первый результат из этого набора запросов:
ModelA.objects.filter(...).order_by('type_of_input').first()
Другим методом может быть полное исключение источников "USER":
ModelA.objects.exclude(type_of_input="USER")
В итоге, расширив ответ 0sVoid, мы получили эквивалент
ModelA.objects.filter(...).order_by('date', 'type_of_input').distinct('date').
Это привело к получению одной строки на дату, отдавая приоритет "SOURCE"
type_of_input
над "USER"
.
Примечание: В дальнейшем возникла еще одна проблема, связанная с агрегацией по одному из столбцов, которая потребовала подзапроса, чтобы обойти GROUP BY
.