Преобразование SQL в то, что может использовать Django

Я работаю над преобразованием относительно сложного SQL в то, с чем может играть Django. Я стараюсь не использовать только необработанный SQL, поскольку я думаю, что игра со стандартным набором инструментов Django поможет мне узнать больше о Django.

Мне уже удалось разбить части sql на куски, и я решаю их по частям, чтобы сделать все немного проще.

Вот SQL, о котором идет речь:

SELECT i.year, i.brand, i.desc, i.colour, i.size, i.mpn, i.url, 
COALESCE(DATE_FORMAT(i_eta.eta, '%M %Y'),'Unknown') 
as eta 
FROM i 
JOIN i_eta ON i_eta.mpn = i.mpn 
WHERE category LIKE 'kids' 
ORDER BY i.brand, i.desc, i.colour, FIELD(size, 'xxl','xl','l','ml','m','s','xs','xxs') DESC, size+0, size

Вот что у меня есть (пытаюсь преобразовать строку за строкой):

(grabbed automatically when performing filters)
(have to figure out django doc on coalesce for syntax)
db alias haven't been able to find yet - it is crucial since there is a db view that requires it
already included in the original q
.select_related?
.filter(category="kids")
.objects.order_by('brand','desc','colour') - don't know how to deal with SQL FIELDS

Любой совет будет оценен по достоинству!

Вот как я бы это структурировал.

Во-первых, я предполагаю, что ваши модели для i и i_eta выглядят примерно так:

class I(models.Model):
    mpn = models.CharField(max_length=30, primary_key=True)
    year = models.CharField(max_length=30)
    brand = models.CharField(max_length=30)
    desc = models.CharField(max_length=100)
    colour = models.CharField(max_length=30)
    size = models.CharField(max_length=3)

class IEta(models.Model):
    i = models.ForeignKey(I, on_delete=models.CASCADE)
    eta = models.DateField()

Общие мысли:

  1. Для написания coalesce в Django: Я бы не стал заменять нули на "Unknown" в ORM. Это проблема презентационного уровня: она должна решаться в шаблоне.

    .
  2. Для форматирования даты вы можете сделать форматирование даты в Python.

  3. Не уверен, что такое псевдоним БД.

  4. Для использования нескольких таблиц вместе, вы можете использовать либо select_related(), prefetch_related(), либо ничего не делать.

    1. select_related() будет выполнять объединение.
    2. prefect_related() получит идентификаторы внешних ключей из первого набора запросов, затем создаст запрос типа SELECT * FROM table WHERE id in (12, 13, 14).
    3. Ничего не делая, запрос будет работать автоматически, но имеет недостаток в виде проблемы SELECT N+1.

    Я обычно предпочитаю prefetch_related().

  5. Для настройки порядка сортировки поля size у вас есть три варианта. Я предпочитаю вариант 1, но подойдет любой из трех.

    1. Денормализуйте критерии сортировки. Добавьте новое поле с именем size_numeric. Переопределите метод save(), чтобы заполнять это поле при сохранении новых экземпляров, присваивая xxl значение 1, xl значение 2 и т.д.
    2. .
    3. Сортировка в Python. По сути, вы используете встроенные методы сортировки Python для выполнения сортировки, а не сортируете в базе данных. Это не очень хорошо работает, если у вас тысячи результатов.
    4. Вызовите функцию MySQL. По сути, используя annotate(), вы добавляете вывод функции в набор запросов. order_by() может сортировать по этой функции.
    5. .
Вернуться на верх