Перейти к содержанию

Синхронизация иерархий

Введение

Синхронизация иерархий (sync) — это процесс, который приводит структуру уровней и элементов иерархии в согласованное состояние, обновляет дерево (MPTT), связи между уровнями и таблицы классификаторов. Этот механизм обеспечивает корректную работу всех функций, зависящих от иерархических связей.

Что делает синхронизация?

  • Перестраивает дерево уровней (MPTT), используя поле child как родительскую связь.
  • Обновляет связи между уровнями: parents, ancestors, descendants.
  • Синхронизирует вспомогательные таблицы (dim-таблицы для классификаторов).
  • Обеспечивает согласованность связей между элементами (items) на разных уровнях.
  • Очищает устаревшие таблицы и индексы, создаёт новые при необходимости.

Основные этапы sync

  1. Перестроение дерева (MPTT):

  2. Используется метод Level.objects.rebuild(), который пересчитывает поля lft, rght, tree_id, level для всех уровней.

  3. Дерево строится по полю child (в отличие от классического parent).

  4. Обновление связей между уровнями:

  5. Для каждого уровня вызывается level.sync().

  6. Внутри происходит:

    • Обновление M2M-связей parents на основе структуры дерева (child → parent).
    • Обновление M2M-связей ancestors (все предки уровня).
    • Вызов вспомогательных методов: get_parents_with_self, get_all_parents_with_self, update_relations.
  7. Синхронизация структуры и контента:

  8. Создаются/обновляются dim-таблицы для каждого уровня (таблицы классификаторов).

  9. Удаляются устаревшие dim-таблицы.
  10. Для каждого уровня вызывается level.sync(with_children=False, sync_structure=True, sync_content=True).
  11. Обновляются связи между элементами (items) на разных уровнях (таблицы core_hierarchy_item_parents, core_hierarchy_item_all_parents).

  12. Рекурсивная обработка дочерних уровней:

  13. Для каждого дочернего уровня (child) рекурсивно вызывается sync.

Ключевые структуры данных и код

  • Модель Level — основной класс, описывающий уровень иерархии. Дерево строится по полю child (см. class MPTTMeta: parent_attr = "child").
  • Метод Level.sync() — основной вход для синхронизации одного уровня. Делегирует работу функции sync из planiqum.core.hierarchy.libs.sync.
  • Функция sync(level, ...) — реализует логику синхронизации:

  • Обновляет связи parents на основе MPTT-структуры.

  • Синхронизирует структуру (dim-таблицы, индексы).
  • Синхронизирует контент (items, связи между ними).
  • Рекурсивно вызывает sync для дочерних уровней.

  • Вспомогательные методы:

  • get_parents_with_self, get_all_parents_with_self, update_relations — используются для вычисления и обновления связей между уровнями.

  • get_descendants, get_ancestors — работают по MPTT-структуре.

  • Dim-таблицы — отдельные таблицы для хранения классификаторов на каждом уровне. Их структура и наполнение синхронизируются при каждом запуске sync.

  • Связи между элементами — таблицы core_hierarchy_item_parents и core_hierarchy_item_all_parents обновляются для отражения актуальных связей между элементами разных уровней.

Когда требуется запускать sync?

  • После загрузки или изменения структуры уровней (например, после импорта из yaml/csv/xlsx).
  • После массового обновления или удаления уровней.
  • После программных изменений дерева (например, через API или админку).

Пример вызова sync

from planiqum.core.hierarchy.models import Level

# Перестроить всё дерево и синхронизировать все уровни
def full_sync():
    Level.objects.sync()

См. также