Проверка целостности таблиц фактов¶
Обзор¶
В системе Planiqum предусмотрены команды для проверки и анализа целостности таблиц фактов параметров. Эти инструменты помогают выявить проблемы с данными, отсутствующие индексы и дубликаты.
Доступные команды¶
check_fact_tables_integrity- комплексная проверка целостности таблиц фактовshow_duplicates- детальный анализ и экспорт дубликатов
Команда check_fact_tables_integrity¶
Назначение¶
Выполняет комплексную проверку целостности таблиц фактов для невычисляемых параметров.
Что проверяется¶
1. Наличие таблиц фактов¶
Для всех параметров с is_calculated=False проверяется наличие таблицы фактов в базе данных.
Ошибка: Отсутствует таблица фактов для невычисляемого параметра.
2. Наличие полей¶
Для существующих таблиц проверяется наличие всех необходимых колонок:
- Dim-колонки: для всех измерений параметра
- Measure-колонки: для мер с
is_calculated=Falseиcalculation_method='generated_column'
Ошибка: Отсутствуют необходимые поля в таблице.
Примечание: Меры с другими calculation_method (Raw SQL, Custom Aggregation и т.д.) не должны иметь колонок в таблице фактов.
3. Наличие индексов¶
Проверяется наличие индексов согласно стандарту синхронизации:
- Индивидуальные индексы: на каждую dim-колонку
- Композитный уникальный индекс: на все dim-колонки (предотвращает дубликаты)
Ошибка: Отсутствуют необходимые индексы.
Критично: Отсутствие уникального композитного индекса позволяет создавать дубликаты!
4. Дубликаты (опционально)¶
Для параметров без уникального композитного индекса проверяется наличие дубликатов по dim-колонкам.
⚠️ Ресурсоёмкая операция! Включается флагом --check-duplicates.
Выводится:
- Количество дубликатов
- Общее количество записей
- Процент дубликатов от общего числа записей
5. Статистика заполненности (опционально)¶
Собирается статистика по таблицам:
- Общее количество записей
- Количество записей, где все меры NULL
- Процент пустых записей
⚠️ Ресурсоёмкая операция! Включается флагом --collect-stats.
Использование¶
Синтаксис¶
python manage.py check_fact_tables_integrity [опции]
Опции¶
| Опция | Описание | По умолчанию |
|---|---|---|
--parameters PARAM1 PARAM2 ... |
Список ключей параметров для проверки | Все невычисляемые |
--check-duplicates |
Проверять дубликаты (ресурсоёмко) | false |
--collect-stats |
Собирать статистику заполненности (ресурсоёмко) | false |
--exact-count |
Точный подсчёт записей | false (быстрая оценка) |
--format {table\|json} |
Формат вывода | table |
--workers N |
Количество параллельных воркеров | 1 |
Примеры¶
Базовая проверка:
# Проверить все невычисляемые параметры
python manage.py check_fact_tables_integrity
Проверка конкретных параметров:
python manage.py check_fact_tables_integrity --parameters sales_plan revenue_plan
Полная проверка с дубликатами и статистикой:
python manage.py check_fact_tables_integrity \
--check-duplicates \
--collect-stats \
--exact-count \
--workers 4
Экспорт результатов в JSON:
python manage.py check_fact_tables_integrity \
--format json > integrity_report.json
Формат вывода¶
Табличный формат (по умолчанию)¶
Результаты выводятся в виде markdown таблиц с выравненными колонками.
Пример вывода:
=== ИТОГИ ===
Параметров проверено: 149
Найдено ошибок: 110
--- ОШИБКИ: Отсутствующие индексы (99) ---
| Ключ параметра | Название | Индексы измерений | Уникальный индекс |
|-------------------------------------|---------------------------------|-------------------|-------------------|
| demand__sellin_history_weekly | ВП - история (недели) | ✓ | ❌ ОТСУТСТВУЕТ |
| demand__sellin_history_clean_weekly | ВП - очищенная история (недели) | ✓ | ❌ ОТСУТСТВУЕТ |
--- ДУБЛИКАТЫ (3) ---
| Ключ параметра | Название | Всего записей | Дубликаты | Процент |
|-------------------------------------|---------------------------------|---------------|-----------|---------|
| demand__sellin_history_clean_weekly | ВП - очищенная история (недели) | 7,236,107 | 7,112,012 | 98.29% |
| demand__sellin_history_weekly | ВП - история (недели) | 3,406,842 | 3,282,747 | 96.36% |
| project__order_history_weekly | История заказов | 2,108,637 | 2,011,768 | 95.41% |
--- СТАТИСТИКА (3) ---
| Ключ параметра | Название | Всего записей | Пустых записей | Процент пустых |
|-------------------------------------|---------------------------------|---------------|----------------|----------------|
| working_days_calendar | Календарь рабочих дней | 1,826 | 0 | 0.0% |
| demand__sellin_history_weekly | ВП - история (недели) | 3,406,842 | 0 | 0.0% |
✗ Обнаружены проблемы с целостностью данных!
JSON формат¶
{
"summary": {
"parameters_checked": 3,
"total_errors": 4,
"has_duplicates": true
},
"errors": {
"missing_table": [],
"missing_fields": {},
"missing_indexes": {
"sales_plan": {
"parameter_name": "План продаж",
"missing_dimension_indexes": [],
"missing_unique_index": true
}
},
"duplicates": {
"sales_plan": {
"parameter_name": "План продаж",
"duplicate_count": 3282747,
"total_records": 3406842,
"duplicate_percent": 96.36
}
}
},
"statistics": {
"sales_plan": {
"parameter_name": "План продаж",
"total_records": 3406842,
"null_measures_records": 0,
"null_measures_percent": 0.0
}
}
}
Производительность¶
Подсчёт записей¶
- Быстрая оценка (по умолчанию):
pg_class.reltuples- очень быстро, может быть неточно на 5-10% - Точный подсчёт (
--exact-count):COUNT(*)- медленнее, абсолютно точно
Параллелизм¶
Используйте --workers для ускорения проверки большого количества параметров:
# Последовательно (безопасно, медленнее)
python manage.py check_fact_tables_integrity --workers 1
# Параллельно (быстрее в 2-4 раза)
python manage.py check_fact_tables_integrity --workers 4
Оценка времени выполнения¶
| Опции | Параметров | Время |
|---|---|---|
| Без опций | 149 | ~2-5 сек |
--check-duplicates |
149 | ~30-120 сек |
--collect-stats |
149 | ~10-30 сек |
--check-duplicates --collect-stats |
149 | ~60-180 сек |
С --workers 4 |
149 | В 2-3 раза быстрее |
Интерпретация результатов¶
Критичные ошибки¶
- Отсутствующие таблицы → Требуется синхронизация параметра
- Отсутствующие поля → Требуется синхронизация параметра
- Отсутствует уникальный индекс → Высокий риск дубликатов, требуется синхронизация
Важные предупреждения¶
- Найдены дубликаты → Требуется агрегация данных перед созданием уникального индекса
- Высокий процент пустых записей → Возможно, данные импортируются некорректно
Рекомендации по устранению¶
Отсутствующие таблицы/поля/индексы:
from planiqum.core.parameters.models import Parameter
# Синхронизировать конкретный параметр
param = Parameter.objects.get(key='sales_plan')
param.sync()
# Синхронизировать все параметры с ошибками
for param_key in ['sales_plan', 'revenue_plan']:
param = Parameter.objects.get(key=param_key)
param.sync()
Дубликаты:
Перед созданием уникального индекса необходимо агрегировать дубликаты. См. раздел Устранение дубликатов.
Использование из Python¶
from planiqum.core.parameters.scripts.check_fact_tables_integrity import check_fact_tables_integrity
# Проверка всех параметров
results = check_fact_tables_integrity()
# Проверка конкретных параметров
results = check_fact_tables_integrity(
parameters=['sales_plan', 'revenue_plan'],
check_duplicates=True,
collect_stats=True,
exact_count=False,
workers=4
)
# Анализ результатов
if results['summary']['total_errors'] > 0:
print(f"Найдено ошибок: {results['summary']['total_errors']}")
# Параметры с отсутствующими таблицами
for item in results['errors']['missing_table']:
print(f"Отсутствует таблица: {item['key']}")
# Параметры с дубликатами
for key, data in results['errors']['duplicates'].items():
print(f"{key}: {data['duplicate_count']} дубликатов ({data['duplicate_percent']}%)")
Команда show_duplicates¶
Назначение¶
Выводит и экспортирует дубликаты из таблицы фактов конкретного параметра для детального анализа.
Режимы работы¶
1. Режим grouped (по умолчанию)¶
Группирует дубликаты и показывает количество повторений каждой комбинации.
Формат вывода:
dim_column1,dim_column2,...,duplicate_count
value1,value2,...,177
Использование:
Идеально для анализа какие комбинации измерений чаще всего дублируются.
2. Режим unique¶
Выводит только уникальные комбинации dim-колонок без количества повторений.
Формат вывода:
dim_column1,dim_column2,...
value1,value2,...
Использование:
Полезно для получения списка проблемных комбинаций для последующей обработки.
3. Режим full¶
Выводит все дублирующиеся строки со всеми полями таблицы (включая id и меры).
Формат вывода:
id,dim_column1,dim_column2,...,measure_column1,...
100,value1,value2,...,1000,...
101,value1,value2,...,1000,...
Использование:
Необходим для детального анализа конкретных дублирующихся записей.
Использование¶
Синтаксис¶
python manage.py show_duplicates <parameter> [опции]
Опции¶
| Опция | Описание | По умолчанию |
|---|---|---|
parameter (обязательно) |
Ключ параметра | - |
--mode {grouped\|full\|unique} |
Режим вывода | grouped |
--limit N |
Максимальное количество групп/строк | Консоль: 100 Файл: без ограничений |
--output FILE |
Путь к CSV файлу для экспорта | Вывод в консоль |
Примеры¶
Быстрый просмотр топ-10 групп:
python manage.py show_duplicates sales_plan --limit 10
Экспорт всех дубликатов в файл:
python manage.py show_duplicates sales_plan --output duplicates.csv
Экспорт топ-500 групп:
python manage.py show_duplicates sales_plan --limit 500 --output top_500.csv
Получить список уникальных комбинаций:
python manage.py show_duplicates sales_plan --mode unique --output unique_combos.csv
Экспорт всех дублирующихся строк:
python manage.py show_duplicates sales_plan --mode full --output all_rows.csv
Формат вывода¶
Вывод в консоль¶
Если групп ≤ 1000:
Выводится полная markdown таблица:
Всего групп дубликатов в таблице: 150
Общее количество дубликатов в таблице: 1,500
Показаны первые 150 групп:
| dim_client | dim_product | duplicate_count |
|------------|-------------|-----------------|
| 123 | 456 | 25 |
...все группы...
Если групп > 1000:
Выводятся первые 10 групп + предупреждение:
Всего групп дубликатов в таблице: 97,417
Общее количество дубликатов в таблице: 3,282,747
Первые 100 групп:
| dim_client | dim_product | duplicate_count |
|------------|-------------|-----------------|
| 1061383 | 977785 | 177 |
| 1061383 | 863683 | 177 |
...первые 100...
... и ещё 97,317 групп не показано
Для просмотра всех данных используйте опцию --output для экспорта в файл
или --limit для увеличения количества показанных строк (по умолчанию: 100)
Экспорт в файл¶
С limit:
python manage.py show_duplicates sales_plan --limit 50 --output dup.csv
Экспортируется ровно 50 групп в файл + превью в консоли (если ≤ 100).
Без limit:
python manage.py show_duplicates sales_plan --output all_dup.csv
Экспортируются ВСЕ группы дубликатов в файл (без ограничений).
Интерпретация результатов¶
Пример вывода grouped режима¶
| dim_client | dim_product | duplicate_count |
|------------|-------------|-----------------|
| 123 | 456 | 177 |
Означает:
- Комбинация
client=123, product=456встречается 177 раз в таблице - Из них 1 оригинал и 176 дубликатов
- Эти 176 лишних строк можно удалить
Общая статистика¶
Всего групп дубликатов в таблице: 97,417
Общее количество дубликатов в таблице: 3,282,747
Означает:
- В таблице есть 97,417 уникальных комбинаций измерений, которые повторяются
- Суммарно это даёт 3,282,747 лишних строк (дубликатов)
- Если удалить дубликаты, таблица уменьшится на 3,282,747 записей
Использование из Python¶
from planiqum.core.parameters.scripts.show_duplicates import show_duplicates
# Получить дубликаты
data = show_duplicates(
parameter_key='sales_plan',
mode='grouped',
limit=100,
output_file='/tmp/duplicates.csv'
)
# Анализ результатов
print(f"Групп дубликатов: {data['total_groups']}")
print(f"Всего дубликатов: {data['total_duplicates']}")
print(f"Заголовки: {data['headers']}")
print(f"Первая группа: {data['rows'][0]}")
Устранение дубликатов¶
Процесс устранения¶
- Экспорт дубликатов для анализа:
python manage.py show_duplicates sales_plan --output sales_duplicates.csv
- Анализ дубликатов:
Открыть CSV в Excel/LibreOffice и проанализировать: - Какие комбинации измерений дублируются? - Есть ли закономерность? - Почему возникли дубликаты?
- Агрегация дубликатов:
⚠️ Перед созданием уникального индекса необходимо агрегировать дубликаты!
Варианты агрегации: - SUM: суммирование значений мер - AVG: среднее значение - MAX/MIN: выбор максимального/минимального - FIRST: оставить первую запись
Пример агрегации (через Django shell):
from django.db import connection
from planiqum.core.libs.db import execute_query
# Создаём временную таблицу с агрегированными данными
execute_query("""
CREATE TABLE fact__sales_plan_tmp AS
SELECT
MIN(id) as id,
dim_product,
dim_region,
dim_period,
SUM(m_revenue) as m_revenue,
SUM(m_quantity) as m_quantity
FROM fact__sales_plan
GROUP BY dim_product, dim_region, dim_period
""")
# Переименовываем таблицы
execute_query("DROP TABLE fact__sales_plan")
execute_query("ALTER TABLE fact__sales_plan_tmp RENAME TO fact__sales_plan")
# Синхронизируем параметр (создаст индексы)
from planiqum.core.parameters.models import Parameter
param = Parameter.objects.get(key='sales_plan')
param.sync()
- Синхронизация параметра:
После агрегации запустите синхронизацию для создания уникального индекса:
param.sync()
- Проверка результатов:
python manage.py check_fact_tables_integrity --parameters sales_plan
python manage.py show_duplicates sales_plan
Автоматическая агрегация (TODO)¶
⚠️ В будущих версиях: Планируется автоматическая агрегация при создании уникального индекса (см. TODO в коде синхронизации).
Сценарии использования¶
Проверка перед деплоем¶
# Быстрая проверка всех параметров
python manage.py check_fact_tables_integrity --workers 4
# Если найдены ошибки - синхронизировать проблемные параметры
Периодический мониторинг¶
# Cron job для ежедневной проверки
0 2 * * * cd /path/to/project && python manage.py check_fact_tables_integrity \
--format json > /var/log/planiqum/integrity_$(date +\%Y\%m\%d).json
Анализ проблемных таблиц¶
# 1. Найти параметры с дубликатами
python manage.py check_fact_tables_integrity --check-duplicates
# 2. Детально изучить дубликаты
python manage.py show_duplicates sales_plan --output sales_dup.csv
# 3. Проанализировать в Excel
# 4. Агрегировать дубликаты
# 5. Синхронизировать параметр
Очистка базы данных¶
# 1. Найти таблицы с высоким процентом пустых записей
python manage.py check_fact_tables_integrity --collect-stats
# 2. Удалить пустые записи
python manage.py shell -c "
from planiqum.core.libs.db import execute_query
execute_query('DELETE FROM fact__sales_plan WHERE m_revenue IS NULL AND m_cost IS NULL')
"
API для разработчиков¶
check_fact_tables_integrity¶
from planiqum.core.parameters.scripts.check_fact_tables_integrity import (
check_fact_tables_integrity,
FactTableIntegrityChecker
)
# Простой вызов
results = check_fact_tables_integrity(
parameters=['sales_plan', 'revenue_plan'], # или None для всех
check_duplicates=True,
collect_stats=True,
exact_count=False,
workers=4,
progress_callback=lambda curr, total, key: print(f"{curr}/{total}: {key}")
)
# Использование класса напрямую
checker = FactTableIntegrityChecker(
parameters=None, # Все параметры
check_duplicates=True,
collect_stats=True,
exact_count=False,
workers=4
)
results = checker.check()
# Обработка результатов
for key, data in results['errors']['duplicates'].items():
print(f"{key}: {data['duplicate_percent']}% дубликатов")
show_duplicates¶
from planiqum.core.parameters.scripts.show_duplicates import (
show_duplicates,
DuplicatesExporter
)
# Простой вызов
data = show_duplicates(
parameter_key='sales_plan',
mode='grouped',
limit=100,
output_file='/tmp/dup.csv'
)
# Использование класса напрямую
exporter = DuplicatesExporter('sales_plan', mode='grouped', limit=100)
data = exporter.get_duplicates()
# Экспорт
exporter.export_to_csv('/tmp/dup.csv', data)
# Анализ результатов
print(f"Всего групп: {data['total_groups']}")
print(f"Всего дубликатов: {data['total_duplicates']}")
print(f"Заголовки: {data['headers']}")
print(f"Первые 5 групп: {data['rows'][:5]}")
Устранение проблем¶
Ошибка: "Параметр не найден или является вычисляемым"¶
Причина: Команды работают только с невычисляемыми параметрами.
Решение: Проверьте, что параметр существует и is_calculated=False.
Ошибка: "Параметр не имеет измерений"¶
Причина: Для проверки дубликатов параметр должен иметь измерения.
Решение: Эта команда не применима к параметрам без измерений.
Ошибка: "Таблица фактов не существует"¶
Причина: Таблица не создана или была удалена.
Решение: Выполните синхронизацию параметра:
from planiqum.core.parameters.models import Parameter
param = Parameter.objects.get(key='parameter_key')
param.sync()
Слишком долгое выполнение¶
Проблема: Проверка дубликатов занимает слишком много времени.
Решение:
- Используйте
--limitдля ограничения выборки - Проверьте наличие индексов на dim-колонки
- Рассмотрите использование
--workersдля параллелизма
Лучшие практики¶
Регулярная проверка¶
Рекомендуется регулярно (раз в неделю/месяц) проверять целостность таблиц:
python manage.py check_fact_tables_integrity --workers 4
После изменений структуры¶
После изменения измерений или мер параметра всегда проверяйте целостность:
python manage.py check_fact_tables_integrity --parameters modified_parameter
Перед импортом больших объёмов данных¶
Перед импортом убедитесь в наличии уникального индекса:
python manage.py check_fact_tables_integrity --parameters target_parameter
Если индекса нет - сначала синхронизируйте параметр, потом импортируйте данные.
Мониторинг дубликатов¶
Периодически проверяйте наличие дубликатов в критичных параметрах:
# Раз в неделю
python manage.py check_fact_tables_integrity \
--parameters sales_plan revenue_plan order_plan \
--check-duplicates \
--format json > weekly_check.json
Работа с большими таблицами¶
Для таблиц с миллионами записей:
- Используйте быструю оценку (без
--exact-count) - Проверяйте дубликаты только при необходимости
- Используйте параллелизм (
--workers 4) - Экспортируйте результаты в файлы для анализа
Связанные разделы¶
- Синхронизация параметров - подробно о процессе синхронизации
- Импорт данных в параметры - как правильно импортировать данные
- Работа с базой данных - общие принципы работы с БД
Справочная информация¶
Файлы¶
Сценарии: - /src/planiqum/core/parameters/scripts/check_fact_tables_integrity.py - /src/planiqum/core/parameters/scripts/show_duplicates.py
Команды: - /src/planiqum/core/parameters/management/commands/check_fact_tables_integrity.py - /src/planiqum/core/parameters/management/commands/show_duplicates.py
Связанный код¶
- /src/planiqum/core/parameters/libs/sync.py: ParameterTableSynchronizer - синхронизация таблиц фактов
- /src/planiqum/core/parameters/models.py: Parameter - модель параметра
Важно: описанные настройки и сценарии могут отличаться в вашей инсталляции Planiqum
За уточнениями и методологической поддержкой обращайтесь в компанию
ЮНИК СОФТ