Інструмент для автоматизованого експорту даних з OLAP кубів (Microsoft Analysis Services) у файли Excel та CSV з підтримкою CLI, інтерактивного консольного UI, YAML-конфігурації, профілів, планувальника, автоматичних періодів та завантаження у ClickHouse, DuckDB та PostgreSQL.
- Інтерактивне консольне меню — wizard-режим без аргументів (InquirerPy + rich)
- Єдина YAML-конфігурація — всі налаштування в
config.yaml, секрети окремо в.env - CLI аргументи — гнучке управління через командний рядок
- Автоматичні періоди — 7 варіантів розумних періодів (останні N тижнів, поточний місяць, квартал і т.д.)
- Профілі — збереження наборів налаштувань для різних сценаріїв (перевизначають будь-яку секцію конфігу)
- Планувальник — автоматичне виконання експортів за розкладом
- Стиснення — ZIP архівація результатів
- Два методи аутентифікації — Windows (SSPI) та Логін/Пароль
- Шифрування облікових даних — безпечне зберігання паролів з прив'язкою до машини
- Потоковий експорт — ефективна робота з великими наборами даних
- 3 аналітичних sink'и — ClickHouse, DuckDB (REST API), PostgreSQL (COPY FROM STDIN)
- Паралельний імпорт XLSX — єдиний скрипт для всіх sink'ів з thread pool
- Рекомендовано: Python 3.13
- Підтримується: Python 3.8 — 3.13
- Не підтримується: Python 3.14+ (несумісність pythonnet)
Важливо: Python 3.14 не підтримує pythonnet, тому OLAP-підключення працює лише на Python 3.8–3.13.
pip install -r requirements.txtОсновні бібліотеки:
pythonnet— .NET інтероп для ADOMD.NET (Python 3.8–3.13)pandas,xlsxwriter— обробка та експорт данихPyYAML— конфігурація та профіліschedule— планувальник задачcryptography— шифрування облікових данихpython-dotenv,colorama— завантаження .env та кольоровий вивідrich,InquirerPy— інтерактивний консольний UI (панелі, таблиці, fuzzy select)clickhouse-connect— завантаження даних у ClickHouserequests— DuckDB REST APIpsycopg2-binary— завантаження даних у PostgreSQL (COPY FROM STDIN)python-calamine— швидке читання Excel (Rust, 3-10x швидше за openpyxl)
Скопіюйте .env.example в .env та вкажіть параметри підключення:
cp .env.example .env.env містить тільки секрети (сервер, БД, автентифікація):
OLAP_SERVER=10.40.0.48
OLAP_DATABASE=Sells
OLAP_AUTH_METHOD=LOGIN # SSPI або LOGIN
OLAP_DOMAIN=EPICENTRK
OLAP_CREDENTIALS_ENCRYPTED=true
OLAP_CREDENTIALS_FILE=.credentialsВсі не-секретні налаштування знаходяться у config.yaml. За замовчуванням він уже містить розумні значення. За потреби скопіюйте з прикладу та відредагуйте:
cp config.yaml.example config.yamlДив. config.yaml.example для повного переліку налаштувань.
# Без аргументів — інтерактивне меню
python olap.py
# З аргументами — CLI режим
python olap.py --last-weeks 4 --format xlsx
# При першому запуску з LOGIN методом введіть облікові дані —
# вони будуть зашифровані та збережені автоматичноПри запуску без аргументів (python olap.py) відкривається консольне меню зі стрілковою навігацією:
┌──────────────────────────────────────┐
│ OLAP Export Tool │
│ Сервер: 10.40.0.48 · Auth: LOGIN │
└──────────────────────────────────────┘
? Оберіть дію:
❯ Експорт з OLAP куба
Імпорт XLSX в аналітику
──────────────
Вийти
Покроковий wizard:
- Вибір профілю (fuzzy search або пропустити)
- Формат (XLSX, CSV, XLSX+CSV, ClickHouse, DuckDB, PostgreSQL)
- Тип періоду (останні тижні, поточний місяць, ручний і т.д.)
- Значення періоду (кількість тижнів або діапазон YYYY-WW:YYYY-WW)
- Стиснення (ZIP або без)
- Підтвердження та запуск
Покроковий wizard:
- Цільовий sink (ClickHouse, DuckDB, PostgreSQL)
- Директорія з XLSX-файлами
- Фільтр по року (опційно)
- Фільтр по тижню (опційно)
- Кількість паралельних воркерів (1–32)
- Dry-run режим (опційно)
- Підтвердження та запуск
# Допомога
python olap.py --help
# Інтерактивне меню
python olap.py
# Очистити збережені облікові дані
python olap.py clear_credentials# Останні 4 тижні
python olap.py --last-weeks 4 --format xlsx --compress zip
# Поточний місяць
python olap.py --current-month --format csv
# Попередній місяць
python olap.py --last-month --format both
# Поточний квартал (Q1-Q4)
python olap.py --current-quarter --compress zip
# Попередній квартал
python olap.py --last-quarter --format xlsx
# З початку року до сьогодні
python olap.py --year-to-date --compress zip
# Ковзаюче вікно 12 тижнів
python olap.py --rolling-weeks 12 --format xlsx# Діапазон періодів
python olap.py --period 2025-01:2025-52 --format xlsx
# Або окремо початок та кінець
python olap.py --start 2025-01 --end 2025-12# Формат: xlsx, csv, both, ch, duck, pg
python olap.py --last-weeks 4 --format both
# Кастомний фільтр
python olap.py --current-month --filter "Побутова техніка"
# Таймаут між запитами
python olap.py --last-quarter --timeout 60
# ZIP стиснення (оригінали зберігаються)
python olap.py --year-to-date --compress zipПрофілі дозволяють зберігати набори налаштувань для різних сценаріїв. Профіль може перевизначити будь-яку секцію з config.yaml.
# Список доступних профілів
python olap.py --list-profiles
# Використання профілю
python olap.py --profile weekly_sales
# Перевизначення параметрів профілю через CLI
python olap.py --profile weekly_sales --format csv --compress zipСтворіть YAML файл у директорії profiles/:
# profiles/my_report.yaml
name: my_report
description: Мій власний звіт
# Період (секція тільки для профілю)
period:
type: auto
auto_type: last-weeks
auto_value: 4
# Перевизначення секцій з config.yaml
query:
filter_fg1_name: Споживча електроніка
timeout: 30
export:
format: xlsx
compress: zip
xlsx:
streaming: true
# Планувальник (секція тільки для профілю)
schedule:
enabled: true
simple: "every monday at 09:00"Автоматичне виконання експортів за розкладом.
# Запуск за розкладом (одноразове налаштування)
python olap.py --profile weekly_sales --schedule "every monday at 09:00"
# Daemon режим (постійна робота в фоні)
python olap.py --profile weekly_sales --daemon"every monday at 09:00"
"every day at 18:00"
"every 1 week"
"every 3 days at 14:30"
Інструмент підтримує завантаження даних у три аналітичних бекенди. Всі реалізують спільний інтерфейс AnalyticsSink (ABC) з ідемпотентною вставкою (DELETE + INSERT за year_num + week_num).
Метод: clickhouse-connect з LZ4 стисненням
Особливості:
- Автоматичне створення БД та таблиці зі схемою з DataFrame
- Schema evolution — автоматично додає нові колонки через
ALTER TABLE - Thread-local клієнти для паралельного імпорту
Налаштування (.env):
CH_ENABLED=true
CH_HOST=your-clickhouse-host
CH_PORT=8443
CH_USERNAME=default
CH_PASSWORD=your_password
CH_SECURE=true
CH_DATABASE=olap_export
CH_TABLE=salesВикористання:
# Пряме завантаження під час експорту
python olap.py --last-weeks 4 --format chМетод: HTTP REST API до зовнішнього DuckDB-сервісу
Особливості:
- Відправка даних через REST API (без локального DuckDB клієнта)
- Автоматичне визначення типів колонок з pandas DataFrame
- Thread-safe (одна shared сесія для всіх воркерів)
- Batch INSERT з налаштовуваним batch_size
Налаштування (.env):
DUCK_ENABLED=true
DUCK_URL=https://analytics.lwhs.xyz
DUCK_API_KEY=<your-key>
DUCK_TABLE=sales
DUCK_BATCH_SIZE=1000Використання:
python olap.py --last-weeks 4 --format duckМетод: psycopg2 з COPY FROM STDIN WITH (FORMAT CSV)
Особливості:
- Bulk load через COPY (найшвидший метод для PostgreSQL)
\Nяк NULL sentinel- Schema evolution — автоматично додає нові колонки
- SSL підключення (за замовчуванням
sslmode=require) - Не thread-safe — кожен воркер створює власне з'єднання
Налаштування (.env):
PG_ENABLED=true
PG_HOST=localhost
PG_PORT=5432
PG_DATABASE=analytics
PG_USER=analytics
PG_PASSWORD=your_password
PG_SCHEMA=public
PG_TABLE=sales
PG_SSL_MODE=requireВикористання:
python olap.py --last-weeks 4 --format pgЄдиний скрипт scripts/import_xlsx.py імпортує існуючі XLSX-файли у будь-який sink:
# ClickHouse (8 паралельних воркерів)
python scripts/import_xlsx.py --target ch --dir result/ --workers 8
# DuckDB (тільки 2025 рік)
python scripts/import_xlsx.py --target duck --dir result/ --year 2025
# PostgreSQL (конкретний тиждень)
python scripts/import_xlsx.py --target pg --dir result/ --year 2025 --week 10
# Показати файли без завантаження (dry run)
python scripts/import_xlsx.py --target ch --dir result/ --dry-runАбо через інтерактивне меню: python olap.py → "Імпорт XLSX в аналітику".
Для аналізу даних у Excel підключіться через ODBC:
- Встановіть ClickHouse ODBC Driver
- Налаштуйте DSN у Windows ODBC Data Sources (
SSLMode=require, неstrict) - В Excel: Дані → Отримати дані → З інших джерел → З ODBC
- Виберіть DSN та використовуйте Power Query для агрегації даних
Система конфігурації дотримується строгого пріоритету (від найвищого до найнижчого):
- CLI аргументи (
--format,--timeout, тощо) - Профіль (якщо вказано
--profile) - Legacy .env (не-секретні ключі з
.env— з попередженнями про міграцію) - config.yaml (основна конфігурація)
- Вбудовані значення (defaults у dataclass)
| Файл | Призначення |
|---|---|
.env |
Секрети: OLAP сервер/БД, автентифікація, ClickHouse/DuckDB/PostgreSQL підключення |
config.yaml |
Все інше: запити, експорт, форматування, шляхи, відображення |
profiles/*.yaml |
Перевизначення будь-якої секції config.yaml для конкретного сценарію |
query:
filter_fg1_name: Споживча електроніка # Фільтр категорії
timeout: 30 # Таймаут між запитами (сек)
export:
format: xlsx # xlsx, csv, both, ch, duck, pg
compress: none # zip або none
force_csv_only: false # Ігнорувати xlsx навіть якщо вказано
xlsx:
streaming: false # Потоковий запис (менший пік пам'яті)
min_format: false # Без автоширини та freeze panes
csv:
delimiter: ";"
encoding: "utf-8-sig"
quoting: "minimal" # minimal, all, nonnumeric
excel_header:
color: "00365E" # Колір фону заголовків (HEX)
font_color: "FFFFFF" # Колір шрифту заголовків (HEX)
font_size: 11
paths:
adomd_dll: "./lib" # Шлях до бібліотеки ADOMD.NET
result_dir: "result" # Директорія для результатів
display:
ascii_logs: false # ASCII-режим (без emoji)
debug: false
progress_update_interval_ms: 100Повний приклад з описом: config.yaml.example
# OLAP підключення
OLAP_SERVER=10.40.0.48
OLAP_DATABASE=Sells
OLAP_AUTH_METHOD=LOGIN
OLAP_DOMAIN=EPICENTRK
OLAP_CREDENTIALS_ENCRYPTED=true
OLAP_CREDENTIALS_FILE=.credentials
OLAP_USE_MASTER_PASSWORD=false
# ClickHouse
CH_ENABLED=true
CH_HOST=your-clickhouse-host
CH_PORT=8443
CH_USERNAME=default
CH_PASSWORD=your_password
CH_SECURE=true
CH_DATABASE=olap_export
CH_TABLE=sales
# DuckDB REST API
DUCK_ENABLED=true
DUCK_URL=https://analytics.lwhs.xyz
DUCK_API_KEY=your_key
DUCK_TABLE=sales
# PostgreSQL
PG_ENABLED=true
PG_HOST=localhost
PG_PORT=5432
PG_DATABASE=analytics
PG_USER=analytics
PG_PASSWORD=your_password
PG_SCHEMA=public
PG_TABLE=sales
PG_SSL_MODE=requireПовний приклад: .env.example
Якщо config.yaml відсутній — інструмент працює з вбудованими значеннями. Якщо .env містить старі ключі (наприклад FILTER_FG1_NAME, EXPORT_FORMAT), вони все одно застосовуються з попередженням про перенесення у config.yaml.
- Форматовані заголовки (колір, шрифт — налаштовується в
config.yaml) - Автоматична ширина колонок
- Freeze panes
- Потоковий експорт для великих даних (
xlsx.streaming: true)
- Налаштовуваний роздільник (
;,,, tab) - Кодування (utf-8-sig, utf-8)
- Режими цитування (minimal, all, nonnumeric)
- Автоматичне стиснення після експорту
- Збереження оригінальних файлів
- Статистика коефіцієнту стиснення
Windows (SSPI):
OLAP_AUTH_METHOD=SSPIВикористовує Windows автентифікацію поточного користувача.
Логін/Пароль:
OLAP_AUTH_METHOD=LOGIN
OLAP_DOMAIN=EPICENTRK
OLAP_CREDENTIALS_ENCRYPTED=trueПри першому запуску введіть облікові дані. Вони будуть зашифровані та збережені у файл .credentials. Спецсимволи у паролях (;, =, {, }) коректно обробляються.
- Fernet шифрування (cryptography)
- Прив'язка до машини (комп'ютер, користувач, диск)
- Опційний майстер-пароль для додаткового захисту
OLAP_USE_MASTER_PASSWORD=true
OLAP_MASTER_PASSWORD=your_master_passwordpython olap.py clear_credentialsresult/
├── 2025/
│ ├── 2025-01.xlsx
│ ├── 2025-02.xlsx
│ ├── 2025-01_to_2025-12_export_20251224_100530.zip
│ └── ...
└── 2024/
└── ...
Формат назв файлів:
- Один тиждень:
YYYY-WW.xlsx - Кілька тижнів:
YYYY-WW_to_YYYY-WW_export_TIMESTAMP.zip
olap-export-tool/
├── olap.py # Точка входу (без аргументів → меню, з аргументами → CLI)
├── .env # Секрети (не в git)
├── .env.example # Приклад секретів
├── config.yaml # Основна конфігурація
├── config.yaml.example # Приклад конфігурації з описами
├── requirements.txt # Python залежності
│
├── olap_tool/ # Основний пакет
│ ├── core/ # Ядро
│ │ ├── cli.py # Парсинг CLI аргументів
│ │ ├── config.py # Єдина точка конфігурації (AppConfig + build_config)
│ │ ├── runner.py # Основна логіка оркестрації
│ │ ├── periods.py # Автоматичні періоди (7 типів)
│ │ ├── profiles.py # Завантаження YAML профілів
│ │ ├── scheduler.py # Планувальник задач
│ │ ├── compression.py # ZIP стиснення
│ │ ├── progress.py # Прогрес, таймери, анімації
│ │ └── utils.py # Утиліти виводу та форматування
│ │
│ ├── connection/ # OLAP підключення
│ │ ├── connection.py # ADOMD.NET / OleDb через pythonnet
│ │ ├── auth.py # Управління обліковими даними
│ │ ├── security.py # Шифрування (Fernet)
│ │ └── prompt.py # Інтерактивний ввід
│ │
│ ├── data/ # Обробка даних
│ │ ├── queries.py # DAX запити та виконання + dispatch у sink'и
│ │ └── exporter.py # Експорт у XLSX/CSV
│ │
│ ├── sinks/ # Аналітичні бекенди
│ │ ├── base.py # AnalyticsSink ABC + sanitize_df()
│ │ ├── clickhouse.py # ClickHouseSink (clickhouse-connect)
│ │ ├── duckdb.py # DuckDBSink (REST API)
│ │ └── postgresql.py # PostgreSQLSink (psycopg2 COPY)
│ │
│ └── ui/ # Консольний інтерфейс (InquirerPy + rich)
│ ├── menu.py # Головне меню (Експорт / Імпорт / Вийти)
│ ├── olap_export.py # Wizard експорту
│ └── xlsx_import.py # Wizard імпорту XLSX
│
├── scripts/
│ └── import_xlsx.py # Паралельний імпорт XLSX → будь-який sink
│
├── profiles/ # Профілі (YAML)
│ └── weekly_sales.yaml # Приклад: щотижневий звіт
│
├── result/ # Результати експорту
│ └── YYYY/
│ ├── YYYY-WW.xlsx
│ └── *.zip
│
├── logs/ # Логи планувальника
│ └── scheduler_YYYY-MM-DD.log
│
└── lib/ # ADOMD.NET бібліотеки
└── Microsoft.AnalysisServices.AdomdClient.dll
"Не вдалося підключитися до OLAP"
- Перевірте
OLAP_SERVERтаOLAP_DATABASEв.env - Перевірте доступність сервера (
ping 10.40.0.48) - Перевірте файрвол та мережеві налаштування
"Помилка автентифікації"
- Очистіть збережені дані:
python olap.py clear_credentials - Перевірте
OLAP_DOMAINта облікові дані - Для SSPI перевірте права Windows користувача
"ModuleNotFoundError: No module named 'pythonnet'"
pip install pythonnet>=3.0.0Потрібен Python 3.8–3.13.
"ModuleNotFoundError: No module named 'yaml'"
pip install PyYAML>=6.0.0"ModuleNotFoundError: No module named 'clickhouse_connect'"
pip install clickhouse-connect>=0.7.0"ModuleNotFoundError: No module named 'psycopg2'"
pip install psycopg2-binary>=2.9.0"bad value 'strict' for attribute 'SSLMode'"
- Відкрийте ODBC Data Sources → знайдіть DSN → змініть
SSLMode=strictнаSSLMode=require
python olap.py --debug --last-weeks 1Або в config.yaml:
display:
debug: true- Створіть профіль
profiles/weekly_auto.yaml:
name: weekly_auto
description: Автоматичний щотижневий звіт
period:
type: auto
auto_type: last-weeks
auto_value: 1
export:
format: xlsx
compress: zip
schedule:
enabled: true
simple: "every monday at 06:00"- Запустіть daemon:
python olap.py --profile weekly_auto --daemon# Вручну
python olap.py --current-month --format both --compress zip
# Або через профіль
python olap.py --profile monthly_reportpython olap.py --year-to-date --format xlsx --compress zippython olap.py --last-quarter \
--filter "Побутова техніка" \
--format xlsx \
--timeout 60 \
--compress zip# ClickHouse (8 воркерів)
python scripts/import_xlsx.py --target ch --dir result/ --workers 8
# PostgreSQL (тільки 2025 рік)
python scripts/import_xlsx.py --target pg --dir result/ --year 2025
# DuckDB (dry run)
python scripts/import_xlsx.py --target duck --dir result/ --dry-run- config.yaml.example — повний приклад конфігурації з описом всіх параметрів
- .env.example — приклад секретів підключення
- docs/UPGRADE_GUIDE.md — детальний посібник з міграції
v4.0 — Консольне інтерактивне меню (InquirerPy + rich), PostgreSQL sink (psycopg2 COPY), реструктуризація пакету (core/, connection/, data/, sinks/, ui/), єдиний скрипт імпорту scripts/import_xlsx.py.
v3.2 — DuckDB інтеграція: DuckDBSink (REST API), DuckDBConfig, паралельний імпортер.
v3.1 — ClickHouse інтеграція: ClickHouseSink, паралельний імпортер з rich UI, ідемпотентна вставка, python-calamine.
v3.0 — Єдина YAML-конфігурація, AppConfig dataclass, виправлення багів, видалення dead code.
v2.0 — CLI, автоматичні періоди, профілі, планувальник та стиснення файлів.
Дата оновлення: 16 березня 2026