Рубрики
Без рубрики

Django Orm Optimization Советы № 4 Рекурсивный запрос

Рекурсивные звонки часто необходимы, когда у вас есть таблица самооценки, наш пример сегодня будет … Tagged с Python, Django, базой данных, SQL.

Производительность Django (серия 4 частей)

Рекурсивные звонки часто необходимы, когда у вас есть таблица самостоятельных ссылок

Нашим примером сегодня будут элементы и категории, которые пользователь хочет получить подробную информацию о категории элементов к категории root.

Корневая категория > Категория > Подкатегория > категория листьев

#models.py
class Category(models.Model):
    name = models.CharField(max_length=127)
    parent = models.ForeignKey('self', null=True)

Нам нужно внедрить запрос, который получает путь к категории к корне:

Наивное решение:

def path_to_root_category(category_id):
    if category_id is None:
        return []
    category = Category.objects.get(pk=category_id)
    result = path_to_root_category(category.parent_id)
    result.append(category)
    return result

path_to_root_category (4) [<Категория: root>, <категория: категория>, <Категория: подкатегория>, <Категория: Категория листьев>]

Стоимость этой функции составляет 4 запроса (количество узлов на пути) Если у нас есть путь большого количества узлов, это будет так плохо.

Оптимизированное решение:

def path_to_root_category(category_id):
    query = '''
    WITH RECURSIVE parents AS (
        SELECT category.*, 0 AS relative_depth
        FROM category
        WHERE id = %s

        UNION ALL

        SELECT category.*, parents.relative_depth - 1
        FROM category,parents
        WHERE category.id = parents.parent_id
    )
    SELECT id, name, parent_id, relative_depth
    FROM parents
    ORDER BY relative_depth;
    '''
    return Category.objects.raw(query, [category_id])

Результат:

Пояснение запроса

  1. Сначала найдите элемент целевой категории и сделайте его первым элементом родители установлен

  2. Следуйте за родителем всех категорий в родители установить и добавить их в тот же набор

  3. Наконец -то выберите все категории в родители Установить упорядоченный по глубине

Производительность Django (серия 4 частей)

Оригинал: “https://dev.to/shawara/django-orm-optimization-tips-4-recursive-query-4on1”