Синхронизация иерархий ¶
Введение ¶
Синхронизация иерархий (sync) — это процесс, который приводит структуру уровней и элементов иерархии в согласованное состояние, обновляет дерево (MPTT), связи между уровнями и таблицы классификаторов. Этот механизм обеспечивает корректную работу всех функций, зависящих от иерархических связей.
Что делает синхронизация? ¶
- Перестраивает дерево уровней (
MPTT), используя полеchildкак родительскую связь. - Обновляет связи между уровнями: parents, ancestors, descendants.
- Синхронизирует вспомогательные таблицы (dim-таблицы для классификаторов).
- Обеспечивает согласованность связей между элементами (items) на разных уровнях.
- Очищает устаревшие таблицы и индексы, создаёт новые при необходимости.
Основные этапы sync ¶
-
Перестроение дерева (MPTT):
-
Используется метод
Level.objects.rebuild(), который пересчитывает поляlft,rght,tree_id,levelдля всех уровней. -
Дерево строится по полю
child(в отличие от классического parent). -
Обновление связей между уровнями:
-
Для каждого уровня вызывается
level.sync(). -
Внутри происходит:
- Обновление M2M-связей
parentsна основе структуры дерева (child → parent). - Обновление M2M-связей
ancestors(все предки уровня). - Вызов вспомогательных методов:
get_parents_with_self,get_all_parents_with_self,update_relations.
- Обновление M2M-связей
-
Синхронизация структуры и контента:
-
Создаются/обновляются dim-таблицы для каждого уровня (таблицы классификаторов).
- Удаляются устаревшие dim-таблицы.
- Для каждого уровня вызывается
level.sync(with_children=False, sync_structure=True, sync_content=True). -
Обновляются связи между элементами (items) на разных уровнях (таблицы
core_hierarchy_item_parents,core_hierarchy_item_all_parents). -
Рекурсивная обработка дочерних уровней:
-
Для каждого дочернего уровня (child) рекурсивно вызывается sync.
Ключевые структуры данных и код ¶
- Модель
Level— основной класс, описывающий уровень иерархии. Дерево строится по полюchild(см.class MPTTMeta: parent_attr = "child"). - Метод
Level.sync()— основной вход для синхронизации одного уровня. ⚠️ ПЕРЕОПРЕДЕЛЁН для использования Direct Pipeline вместо старого механизма (planiqum.core.hierarchy.libs.sync).
Реализация через Direct Pipeline:
- Синхронизирует структуру dim_*_direct таблиц через DimDirectTableBuilder.sync_structure()
- Синхронизирует структуру dim_*_full таблиц через DimTableFull.sync_structure()
- Синхронизирует контент через sync_dim_direct_from_item() (из Item в dim_*_direct и далее в dim_*_full)
- Поддерживает все параметры (ids, with_children, drop, sync_structure, sync_content)
- Рекурсивно вызывает sync для дочерних уровней
- Метод
LevelManager.sync()— синхронизация всех уровней иерархии. ⚠️ ПЕРЕОПРЕДЕЛЁН для использования Direct Pipeline.
Реализация через Direct Pipeline:
- Перестраивает MPTT дерево
- Удаляет устаревшие dim-таблицы (учитывает dim_*_direct и dim_* таблицы)
- Синхронизирует каждый уровень через Level.sync()
- Метод
Level.dimension_table_name()— возвращает имя dim-full таблицы. ⚠️ ПЕРЕОПРЕДЕЛЁН для использованияDimTableFull.get_table_name(level).
Важно: Метод возвращает имя dim-full таблицы (dim_{key} без суффикса _full), а не dim-direct таблицы (dim_{key}_direct). Это важно для обратной совместимости.
-
Вспомогательные методы:
-
get_parents_with_self,get_all_parents_with_self,update_relations— используются для вычисления и обновления связей между уровнями. -
get_descendants,get_ancestors— работают по MPTT-структуре. -
Dim-таблицы — отдельные таблицы для хранения классификаторов на каждом уровне. В Direct Pipeline используются две таблицы:
dim_{key}_direct— таблицы с прямыми родителямиdim_{key}(без суффикса) — таблицы со всеми предками (dim-full)
Их структура и наполнение синхронизируются при каждом запуске sync.
- Связи между элементами — таблицы
core_hierarchy_item_parentsиcore_hierarchy_item_all_parentsобновляются для отражения актуальных связей между элементами разных уровней (через ItemBridge в Direct Pipeline).
Когда требуется запускать sync? ¶
- После загрузки или изменения структуры уровней (например, после импорта из yaml/csv/xlsx).
- После массового обновления или удаления уровней.
- После программных изменений дерева (например, через API или админку).
Пример вызова sync ¶
from planiqum.core.hierarchy.models import Level
# Перестроить всё дерево и синхронизировать все уровни
def full_sync():
Level.objects.sync()
Переход на Direct Pipeline ¶
⚠️ Важно: Методы Level.sync() и LevelManager.sync() были переопределены для использования Direct Pipeline вместо старого механизма. Это обеспечивает обратную совместимость — все существующие вызовы автоматически используют новый механизм.
Преимущества:
- ✅ Все существующие вызовы level.sync() и Level.objects.sync() автоматически используют Direct Pipeline
- ✅ Не требуется обновление кода в местах использования
- ✅ Полная обратная совместимость
- ✅ Единая точка входа для всех синхронизаций
Подробнее о Direct Pipeline: - Direct Pipeline: Руководство для разработчиков - Синхронизация dim_*_full таблиц - Импорт данных через Direct Pipeline
См. также ¶
Важно: описанные настройки и сценарии могут отличаться в вашей инсталляции Planiqum
За уточнениями и методологической поддержкой обращайтесь в компанию
ЮНИК СОФТ