Huawei Mate XT 2 и Huawei Pura X View
Huawei скоро весь рынок переформатирует :) точнее форм-фрагментирует потом фиг загонят всех обратно в прямоугольники. Ждем телефон для кружочкаф :))
Welcome to my personal place for love, peace and happiness 🤖
Huawei скоро весь рынок переформатирует :) точнее форм-фрагментирует потом фиг загонят всех обратно в прямоугольники. Ждем телефон для кружочкаф :))
В мире разработки и инженерии данных инструменты Apache Airflow и Temporal часто могут восприниматься как конкуренты, поскольку оба решают задачу управления многошаговыми процессами. Однако на практике их философия, архитектура и сценарии использования настолько разные, что сравнивать их корректно можно лишь с четким пониманием контекста задачи.
В этой статье мы разберем, для чего предназначен каждый инструмент, в чем их сильные и слабые стороны, и поможем вам определиться с выбором.
Apache Airflow — это классический оркестратор batch-процессов. Он создавался как решение для управления ETL/ELT-пайплайнами, регулярной загрузки данных, построения отчетов и ML-циклов. Центральная концепция Airflow — DAG (направленный ациклический граф), который описывает зависимости между задачами и обычно запускается по расписанию (например, ежедневно в 6 утра).
Temporal — это платформа для надежного исполнения распределенных бизнес-процессов. Она не просто «запускает задачи», а управляет долгоживущими workflow с сохранением состояния, автоматическими повторами, обработкой сбоев и возможностью ждать внешние события (ответ пользователя, платеж, подтверждение от другой системы). Workflow в Temporal пишутся на обычном коде и выполняются детерминированно.
Airflow — это продвинутый планировщик для задач по расписанию в мире данных.
Temporal — это движок надежного исполнения бизнес-логики в распределенных системах, который «помнит» состояние процесса даже через неделю.
| Критерий | Apache Airflow | Temporal |
| Основное назначение | Оркестрация batch-задач и data pipeline’ов | Надежное выполнение бизнес-процессов и workflow |
| Типичные сценарии | ETL, загрузка данных, отчеты, ML-обучение, backfill | Оформление заказов, платежи, onboarding, Saga-паттерны, фоновые операции |
| Модель выполнения | DAG из задач (Task) | Workflow + Activities |
| Основной фокус | Планирование и запуск по расписанию | Состояние, устойчивость, ретраи, долгие ожидания |
| Работа с расписанием | Отлично (родная функциональность) | Возможна, но не основная цель |
| Долгоживущие процессы (дни/недели) | Не подходит (сложно и неэффективно) | Одно из ключевых преимуществ |
| Управление состоянием | Ограниченное (обычно через внешние хранилища) | Встроенная, полная история выполнения |
| Повторные попытки (retries) | Есть, на уровне задач | Гибкие стратегии, таймауты, компенсации |
| Устойчивость к сбоям | Хорошая для batch-задач | Исключительная (продолжает с места сбоя) |
| Язык разработки | Python (DAG-файлы) | Go, Java, TypeScript, Python и другие |
| Наблюдаемость | UI для DAG, логи, статусы задач | UI с историей событий, ретраями и состоянием workflow |
| Сложность внедрения | Относительно низкая для data-команд | Выше (требует проектирования workflow и инфраструктуры) |
| Идеально подходит для Data Engineering | ✅ Да | ❌ Часто избыточно |
| Идеально подходит для микросервисов | ❌ Ограниченно | ✅ Да |
| Масштабирование | Хорошее, но требует тонкой настройки | Рассчитан на распределенные системы с рождения |
| Основная аудитория | Data Engineers, ML Engineers, аналитики | Backend Engineers, Platform Engineers, команды микросервисов |
На старте Airflow кажется простым, но по мере роста числа DAG’ов и их сложности возникают типичные проблемы:
Вывод: Airflow хорош для периодических, четко структурированных задач с понятным началом и концом. Для сложной бизнес-логики он не предназначен.
Temporal дает суперспособности, но платой за них является более высокая инженерная культура:
Вывод: Temporal не нужен для простых ETL-задач, но незаменим там, где процесс должен «жить» и не умирать при сбоях.
Хотя в классическом data‑инжиниринге безраздельно правит Airflow, современные платформы данных становятся всё более распределёнными, событийно‑ориентированными и критичными к задержкам. В таких экосистемах появляются сценарии, где Temporal оказывается не избыточным, а очень даже востребованным.
Вот несколько примеров, когда Temporal может усилить вашу data‑платформу:
При этом Temporal не заменяет Airflow для стандартных ETL по расписанию. Однако если на вашей платформе данных есть процессы, которые:
— то Temporal может стать вторым (и очень мощным) инструментом в вашем арсенале, работающим плечом к плечу с Airflow.
Примеры: загрузка из CRM в DWH, пересчет отчетов, обучение модели по ночам.
Примеры: оформление заказа, прохождение KYC, обработка платежей, доставка товара, долгий процесс верификации, а также упомянутые выше сложные data‑пайплайны с внешними зависимостями.
Да, и это частая практика в крупных компаниях:
Например, Airflow утром подготавливает агрегированные данные, а Temporal запускает workflow их распределённой валидации и отправки во внешние системы с гарантией доставки. Инструменты не конфликтуют, а дополняют друг друга.
| Airflow | Temporal | |
| Слоган | Планировщик для data-задач | Движок надежных процессов (бизнес и data) |
| Сила | Расписание, простота, Python-экосистема | Состояние, устойчивость, долгие workflow, события |
| Слабость | Сложность с долгими процессами, состоянием | Высокий порог входа, избыточен для простого расписания |
Коротко:
Выбор инструмента — это в первую очередь выбор архитектурного подхода. Не пытайтесь забить гвозди микроскопом, но и не используйте молоток для починки часов — выбирайте то, что соответствует реальной сложности ваших задач. А если сложность смешанная — смело комбинируйте оба решения.
Синтетические данные давно перестали быть просто «искусственной картинкой» — сегодня это полноценный инструмент для тестирования, разработки и даже обучения моделей машинного обучения. В этой статье я на примере реального кода покажу, как с помощью библиотеки SDV ( Synthetic Data Vault ) можно сгенерировать синтетическую копию существующей таблицы из ClickHouse, сохранив её статистические свойства и взаимосвязи.
Весь код, который мы разберём, написан на Python и использует актуальную версию SDV. Спойлер: итоговый скрипт занимает меньше 80 строк, а результат — полностью готовая синтетическая таблица в вашей базе данных.
Synthetic Data Vault (SDV) — это Python-библиотека с открытым исходным кодом, которая стала фактическим стандартом для генерации синтетических табличных данных. Она была создана в MIT, а сегодня развивается компанией DataCebo.
Главная идея SDV проста: вы даёте ей реальные данные, она обучает генеративную модель, а затем эта модель создаёт новые данные, которые статистически неотличимы от оригинала, но при этом не содержат реальных записей.
Ключевые возможности SDV:
SDV умеет работать с одиночными таблицами, связанными таблицами и даже последовательными данными.
SDV предлагает несколько алгоритмов (синтезаторов) на выбор. В нашем примере мы используем `GaussianCopulaSynthesizer` — и вот почему.
| Синтезатор | Принцип работы | Скорость | Когда использовать |
| GaussianCopulaSynthesizer | Классический статистический метод, моделирует данные через многомерное распределение | Очень быстрый | Рекомендуется для старта: быстрая работа, хорошее качество, прозрачность |
| CTGANSynthesizer | Генеративно-состязательная сеть (GAN) | Медленнее | Для данных со сложными зависимостями или большим количеством категориальных признаков |
| TVAESynthesizer | Вариационный автокодировщик | Средняя | Альтернатива GAN, требующая больше данных для обучения |
`GaussianCopulaSynthesizer` отлично справляется со смешанными типами данных, которые встречаются в реальных таблицах: числа, строки, даты. При этом он обучается за секунды даже на десятках тысяч строк. Именно поэтому мы выбрали его для нашего примера.
Перед запуском кода нам потребуется установить несколько пакетов. В нашем проекте мы использовали `uv` — быстрый менеджер пакетов для Python.
uv pip install torch==2.2.2
uv pip install "numpy<2"
uv pip install "scipy<1.13"
uv pip install sdv
uv pip install clickhouse-connectВажно: версии пакетов подобраны так, чтобы избежать конфликтов. На момент написания статьи `torch` версии 2.13.0 не имеет готовых сборок для macOS на Intel, поэтому мы используем `2.2.2`. Также важно зафиксировать `numpy<2` и `scipy<1.13` — более новые версии несовместимы с текущей версией `torch`.
Ниже представлен итоговый скрипт `sdv_py_v5.py`, который мы будем разбирать. Он подключается к ClickHouse, загружает реальные данные, обучает синтезатор, генерирует синтетическую копию и сохраняет результат обратно в базу.
import clickhouse_connect
import pandas as pd
import os
import warnings
from sdv.single_table import GaussianCopulaSynthesizer
from sdv.metadata import SingleTableMetadata
# Подавляем предупреждения (включая депрекацию)
warnings.filterwarnings("ignore")
# Правильный импорт для однотабличных отчётов
from sdmetrics.reports.single_table import QualityReport, DiagnosticReport
# ========== НАСТРОЙКИ ==========
CLICKHOUSE_HOST = 'localhost'
CLICKHOUSE_PORT = 18123
CLICKHOUSE_USER = 'default'
CLICKHOUSE_PASSWORD = 'changeme'
CLICKHOUSE_DATABASE = 'default'
SOURCE_TABLE = 'superstore'
SYNTHETIC_TABLE = f'{SOURCE_TABLE}_synt'
LIMIT_ROWS = 10000
NUM_SYNTHETIC_ROWS = None
# ========== ПОДКЛЮЧЕНИЕ ==========
client = clickhouse_connect.get_client(
host=CLICKHOUSE_HOST,
port=CLICKHOUSE_PORT,
username=CLICKHOUSE_USER,
password=CLICKHOUSE_PASSWORD,
database=CLICKHOUSE_DATABASE
)
# ========== ЗАГРУЗКА ==========
query = f"SELECT * FROM {SOURCE_TABLE} LIMIT {LIMIT_ROWS}"
real_df = client.query_df(query)
print(f"Загружено {len(real_df)} строк")
# Преобразуем числовые колонки (запятая → точка)
numeric_cols = ['sales', 'discount', 'profit']
for col in numeric_cols:
if col in real_df.columns and real_df[col].dtype == 'object':
real_df[col] = real_df[col].str.replace(',', '.').astype(float)
# ========== МЕТАДАННЫЕ ==========
metadata = SingleTableMetadata()
metadata.detect_from_dataframe(real_df)
if os.path.exists('metadata.json'):
os.remove('metadata.json')
metadata.save_to_json('metadata.json')
print("Метаданные сохранены в metadata.json")
# ========== ОБУЧЕНИЕ ==========
print("Начинаем обучение синтезатора...")
synthesizer = GaussianCopulaSynthesizer(metadata)
synthesizer.fit(real_df)
print("Обучение завершено")
# ========== ГЕНЕРАЦИЯ ==========
if NUM_SYNTHETIC_ROWS is None:
NUM_SYNTHETIC_ROWS = len(real_df)
synthetic_df = synthesizer.sample(NUM_SYNTHETIC_ROWS)
print(f"Сгенерировано {len(synthetic_df)} строк")
# ========== ПРЕДПРОСМОТР ==========
print("\nОригинальные данные (первые 5 строк):")
print(real_df.head())
print("\nСинтетические данные (первые 5 строк):")
print(synthetic_df.head())
# ========== ОЦЕНКА КАЧЕСТВА ==========
print("\n--- Диагностика (проверка ошибок) ---")
diagnostic = DiagnosticReport()
diagnostic.generate(real_df, synthetic_df, metadata.to_dict())
print(diagnostic)
print("\n--- Оценка качества (статистическое сходство) ---")
quality = QualityReport()
quality.generate(real_df, synthetic_df, metadata.to_dict())
print(quality)
# ========== СОХРАНЕНИЕ В CLICKHOUSE ==========
client.command(f"CREATE TABLE IF NOT EXISTS {SYNTHETIC_TABLE} AS {SOURCE_TABLE}")
client.insert_df(SYNTHETIC_TABLE, synthetic_df)
print(f"\nСинтетические данные загружены в таблицу {SYNTHETIC_TABLE}")
# ========== СОХРАНЕНИЕ В CSV ==========
synthetic_df.to_csv('synthetic_table.csv', index=False)
print("Синтетические данные также сохранены в synthetic_table.csv")client = clickhouse_connect.get_client(
host=CLICKHOUSE_HOST,
port=CLICKHOUSE_PORT,
username=CLICKHOUSE_USER,
password=CLICKHOUSE_PASSWORD,
database=CLICKHOUSE_DATABASE
)
query = f"SELECT * FROM {SOURCE_TABLE} LIMIT {LIMIT_ROWS}"
real_df = client.query_df(query)Мы подключаемся к ClickHouse через библиотеку `clickhouse-connect` и загружаем данные из таблицы-источника в Pandas DataFrame. Лимит в 10 000 строк — разумный компромисс между качеством обучения и скоростью. Для большинства задач этого объёма достаточно, чтобы синтезатор уловил основные закономерности.
numeric_cols = ['sales', 'discount', 'profit']
for col in numeric_cols:
if col in real_df.columns and real_df[col].dtype == 'object':
real_df[col] = real_df[col].str.replace(',', '.').astype(float)В нашем примере числовые колонки хранятся в ClickHouse как строки с запятой в качестве десятичного разделителя (европейский формат). Перед обучением мы преобразуем их в числа с плавающей точкой — иначе SDV не сможет корректно обработать эти данные.
metadata = SingleTableMetadata()
metadata.detect_from_dataframe(real_df)
metadata.save_to_json('metadata.json')SDV автоматически определяет типы каждой колонки: числовые, категориальные, даты и т.д.. Метаданные сохраняются в JSON-файл — это полезно для воспроизводимости: в следующий раз вы сможете загрузить их, а не пересоздавать заново.
synthesizer = GaussianCopulaSynthesizer(metadata)
synthesizer.fit(real_df)Синтезатор «изучает» ваши данные: анализирует распределения каждой колонки, корреляции между ними, паттерны пропусков. Этот процесс занимает секунды даже на 10 000 строк.
synthetic_df = synthesizer.sample(NUM_SYNTHETIC_ROWS)Метод `sample()` создаёт нужное количество новых записей. В нашем случае мы генерируем столько же строк, сколько было в оригинале. При желании можно увеличить или уменьшить это число — синтезатор умеет масштабировать данные.
diagnostic = DiagnosticReport()
diagnostic.generate(real_df, synthetic_df, metadata.to_dict())
quality = QualityReport()
quality.generate(real_df, synthetic_df, metadata.to_dict())Этот этап — одна из сильных сторон SDV. Мы проверяем два аспекта:
Общий Score 64.24% — это нормальный результат для демонстрационного примера. Для улучшения качества можно переключиться на `CTGANSynthesizer` или увеличить объём обучающих данных.
client.command(f"CREATE TABLE IF NOT EXISTS {SYNTHETIC_TABLE} AS {SOURCE_TABLE}")
client.insert_df(SYNTHETIC_TABLE, synthetic_df)Финальный шаг: создаём новую таблицу с той же структурой, что и исходная, и заполняем её синтетическими данными. Всё готово — вы можете работать с синтетической копией так же, как с реальной таблицей.
ClickHouse — популярная колоночная СУБД для аналитики. Генерация синтетических данных прямо в экосистему ClickHouse открывает широкие возможности:
Альтернативный подход — использование встроенных средств ClickHouse, таких как движок `GenerateRandom`. Однако SDV даёт гораздо более качественные данные, потому что он не просто генерирует случайные значения, а воспроизводит реальные статистические паттерны.
Если качество синтеза (особенно Column Pair Trends) вас не устраивает, вот несколько способов его улучшить:
Мы прошли полный путь: от установки библиотек до готовой синтетической таблицы в ClickHouse. SDV оказался мощным и при этом простым в использовании инструментом — весь процесс уместился в один скрипт на 80 строк.
Главные выводы:
Синтетические данные открывают новые возможности для разработки, тестирования и анализа данных — без рисков, связанных с работой с реальными данными. А SDV даёт в руки инструмент, который превращает эту идею в реальность за считанные минуты.
ПЫСЫ:
Можно еще попробовать так: CTGANSynthesizer
from sdv.single_table import GaussianCopulaSynthesizer, CTGANSynthesizerНо надо будет дольше ждать... и заменить тип в строке на
CTGANSynthesizeruv run sdv_py_v55.py
Загружено 9994 строк
Метаданные сохранены в metadata.json
Начинаем обучение синтезатора...
PerformanceAlert: Using the CTGANSynthesizer on this data is not recommended. To model this data, CTGAN will generate a large number of columns.
Original Column Name Est # of Columns (CTGAN)
Order Date 1236
Ship Date 1334
Ship Mode 4
Customer Name 793
segment 3
Country/Region 1
region 4
category 3
Sub-Category 17
Product Name 1849
sales 5825
quantity 11
discount 12
profit 7287
We recommend preprocessing discrete columns that can have many values, using 'update_transformers'. Or you may drop columns that are not necessary to model. (Exit this script using ctrl-C)Все .. комп полетел)) 5 мин... 7 мин... 15... чем то напоминает майнинг))) .... 20... 30... пойду пожалуй спать ... утром все еще майнит, видимо надо другие параметры указывать и разобраться лучше для чего эта опция. Первая же отработала очень быстро.
Корпоративные системы данных долгое время строились вокруг четких границ: базы данных отвечали за транзакции, хранилища — за аналитику, озера данных — за хранение больших массивов сырой информации, поисковые движки индексировали документы, а векторные базы данных обеспечивали семантический поиск.
Оригинал тут: OceanBase Lakebase: A Unified Data Foundation for AI-Native Applications
Такое разделение работало, пока приложения были детерминированными, а данные — в основном структурированными. AI-приложения ведут себя иначе.
Им может понадобиться профиль клиента вместе с изображениями, аудио- и видеозаписями, PDF-файлами, веб-снимками, векторными эмбеддингами и JSON-документами — и все это для одной бизнес-сущности. В многих компаниях эти данные уже существуют, но они разбросаны по разным системам с разной метаинформацией, политиками доступа и конвейерами обработки. Результат — фрагментированный стек данных, который делает AI-приложения сложными в разработке, управлении и эксплуатации.
OceanBase Lakebase создан именно для решения этой проблемы.
Lakebase — это ядро OceanBase AI Database. Оно объединяет управление мультимодальными данными, оперативную выдачу (online serving), аналитику в реальном времени, гибридный поиск и открытые вычисления в единой архитектуре.
Это не отдельное озеро данных и не традиционная база данных с надстройками AI. Это попытка переосмыслить то, как корпоративные данные должны храниться, управляться, обрабатываться и предоставляться, когда AI-приложения становятся частью производственных систем.
Ключевая идея проста: структурированные бизнес-данные и мультимодальные данные должны управляться в рамках единой платформы с согласованной метаинформацией, правами доступа, управлением жизненным циклом и единым языком запросов.
Ключевое нововведение Lakebase — мультимодальная таблица. В традиционной СУБД таблица описывает структурированные поля: идентификаторы, временные метки, суммы, статусы. В Lakebase таблица может описывать более сложные бизнес-сущности, включающие документы, изображения, аудио, видео, JSON, большие объекты, векторы и результаты работы моделей.
Разные типы данных могут использовать разные форматы хранения в зависимости от размера, паттернов доступа и стоимости. Но с точки зрения пользователя, все они управляются через единую табличную модель, единую метасистему и единую систему управления.
Это дает AI-приложениям более естественную модель данных. Например, обращение в службу поддержки может включать структурированные поля тикета, историю чата, записи звонков, загруженные изображения, диагностические логи и эмбеддинги. Логистическая запись — метаданные заказа, события маршрута, заметки водителя, изображения подтверждения доставки и семантические признаки. С бизнес-точки зрения это не отдельные фрагменты, а разные представления одной сущности.
Lakebase упрощает хранение, поиск, управление и обработку таких сущностей как единого целого.
Lakebase вводит понятие AI-колонок — столбцов, в которых хранятся результаты работы моделей: эмбеддинги, саммари, метки, категории или извлеченные признаки.
Вместо того чтобы выгружать данные во внешний конвейер, генерировать семантические результаты и вручную записывать их обратно, команды могут приблизить обработку моделями к данным. Это дает несколько преимуществ:
AI-приложениям нужен поиск, но не один-единственный вид:
В большинстве AI-стеков эти возможности разнесены по разным системам: транзакционная БД, поисковик, векторная БД и конвейер синхронизации. Для прототипов это работает, но в production возникают проблемы со свежестью данных, согласованностью прав доступа и надежностью.
Lakebase объединяет структурную фильтрацию, полнотекстовый поиск и векторный поиск в едином пути запроса. Это позволяет AI-приложениям получать AI-готовый контекст из свежих операционных и мультимодальных данных без множества внешних индексов, которые могут рассинхронизироваться с источником.
Агенты меняют способ использования баз данных. Они могут читать, писать, искать, планировать, тестировать, изменять состояние, генерировать промежуточные результаты и многократно вызывать инструменты. При этом множество агентов могут работать параллельно, каждый со своей памятью, контекстом, правами и историей выполнения.
Lakebase предоставляет основу для хранения и поиска памяти агентов, контекста сессий, бизнес-состояния и записей выполнения. Он также поддерживает изолированные среды через ветвление (branching) и песочницы (sandboxing), чтобы агенты могли тестировать изменения без прямого воздействия на production-данные.
Цель — не просто помочь агентам получать данные, а помочь им работать безопасно, воспроизводимо и в масштабе.
AI-нагрузки не будут выполняться в рамках одного движка. SQL остается основой для транзакционных и аналитических нагрузок. Spark широко используется для обработки больших данных. Ray и смежные фреймворки — для AI-обработки и распределенных модельных нагрузок.
Lakebase поддерживает S3-совместимое объектное хранение и открытые табличные форматы, такие как Apache Iceberg, позволяя вычислительным движкам (SQL, Spark, Ray) работать с общими данными и метаинформацией. Это сокращает необходимость копирования данных между системами.
Открытые форматы важны, так как снижают зависимость от вендора и улучшают совместимость. Но сами по себе они не дают всех возможностей, необходимых для production-систем: оперативной выдачи, согласованности, поиска, управления и агент-ориентированных функций. Lakebase сочетает открытость с управлением на уровне базы данных и доступом в реальном времени.
OceanBase AI Database включает три основных слоя:
| Продукт | Роль |
| Lakebase | Ядро — управление мультимодальными данными, гибридный поиск, открытое хранение и вычисления, оперативная выдача, агент-ориентированные среды |
| DataStudio | Рабочая среда для производства, управления и сервиса данных — помогает подготавливать, обрабатывать, моделировать и предоставлять данные для приложений, агентов и бизнес-пользователей |
| DataPilot | Бизнес-ориентированный агент для работы с данными через естественный язык: запросы, анализ, генерация отчетов и инсайтов |
В России экосистема OceanBase активно развивается в рамках импортозамещения. Ключевые проекты:
В мае 2026 года на конференции ЦИПР-2026 Сбер представил СУБД О.К.Е.А.Н. — корпоративную систему управления базами данных, построенную на открытом коде OceanBase.
Ключевые характеристики:
Название О.К.Е.А.Н. расшифровывается как:
Решение включено в Единый реестр российского ПО (№ 33689). Как отметил Кирилл Меньшов, старший вице-президент Сбербанка: *«Импортозамещение СУБД — один из приоритетных вопросов для крупного бизнеса сегодня»*.
Продукт Platform V Ocean DB от СберТех — это российская дистрибуция OceanBase с полной поддержкой, сертификацией и гарантией безопасности.
| Проблема | Решение Lakebase |
| Данные разрознены по разным системам | Единая платформа для структурированных и мультимодальных данных |
| Сложность интеграции AI в data-пайплайны | AI-колонки и встроенная генерация эмбеддингов |
| Поиск требует нескольких систем | Гибридный поиск (ключевые слова + векторы + фильтры) в одном запросе |
| Агенты работают небезопасно | Ветвление, песочницы, изоляция данных |
| Привязка к вендорам и закрытым форматам | Поддержка S3, Iceberg, SQL, Spark, Ray |
OceanBase Lakebase — это попытка переосмыслить корпоративную платформу данных для эпохи AI. Она объединяет мультимодальные данные, гибридный поиск, открытые вычисления и управление на уровне базы данных в единой архитектуре, чтобы предприятия могли строить AI-приложения на надежной, согласованной и масштабируемой основе.
В России эта технология получает вторую жизнь в рамках инициативы О.К.Е.А.Н. от СберТех, предоставляя крупному бизнесу возможность мигрировать с иностранных СУБД на российскую платформу без потери производительности и с полной поддержкой.
В современном мире данных всё чаще требуется не только предоставлять пользователям интерактивные инструменты для анализа, но и жёстко контролировать, кто и к каким данным может обращаться. Классический подход — встраивать логику доступа прямо в код приложения — быстро становится негибким и трудно поддерживаемым. На помощь приходят специализированные решения: Marimo для построения дашбордов и OPA (Open Policy Agent) для централизованного управления политиками доступа.
В этой статье мы разберём, как написать простое приложение на Marimo, которое проверяет права пользователя через OPA, а затем обсудим, как эта связка может быть расширена на полноценный дашборд, работающий с Trino и управляющий доступом к данным на разных уровнях.
Marimo (https://github.com/marimo-team/marimo) — это современный интерактивный блокнот для Python, который сочетает в себе удобство Jupyter с реактивностью и возможностью превращать блокнот в веб-приложение. В отличие от классических блокнотов, Marimo автоматически пересчитывает ячейки при изменении входных данных, что делает его идеальным для создания дашбордов и инструментов анализа.
OPA (Open Policy Agent: https://www.openpolicyagent.org) — это универсальный движок политик с открытым исходным кодом. Он позволяет описывать правила доступа на языке Rego (декларативном, похожем на JSON) и принимать решения на основе входных данных (input). OPA работает как отдельный сервис, принимающий запросы и возвращающий разрешено или запрещено действие. Такой подход отделяет политики от кода приложения, упрощая их изменение, аудит и повторное использование.
Представьте, что у нас есть дашборд, в котором разные пользователи могут видеть разные разделы. Вместо того чтобы хардкодить условия в Python, мы выносим логику в OPA.
Ниже приведён фрагмент кода на Marimo, который реализует минимальный интерфейс для проверки доступа:
Запускаем OPA
podman run -d --name opa-server -p 8181:8181 openpolicyagent/opa \
run --server --addr=0.0.0.0:8181 --log-level debugСоздаем политику Rego
nano policy.rego
package app.authz
default allow = false
allow if {
input.user.role == "admin"
}Отправляем политику в OPA:
curl -X PUT --data-binary @policy.rego http://localhost:8181/v1/policies/my_policyДалее запускаем новый блокнот Marimo
mkdir marimo-opa
cd marimo-opa
uv init
uv add marimo requests
uv run marimo edit app.pyа теперь само приложение Marimo
import marimo as mo
import requests
# Элементы управления
user_role = mo.ui.dropdown(["user", "admin"], value="user", label="Роль пользователя:")
resource = mo.ui.text(value="dashboard", label="Ресурс:")
submit = mo.ui.button(label="Проверить доступ")
mo.hstack([user_role, resource, submit])После нажатия кнопки код отправляет запрос к OPA:
mo.stop(not submit.value, mo.md("*Нажмите кнопку для проверки прав*"))
opa_url = "http://localhost:8181/v1/data/app/authz/allow"
payload = {
"input": {
"user": {"role": user_role.value},
"resource": resource.value
}
}
try:
response = requests.post(opa_url, json=payload).json()
is_allowed = response.get("result", False)
status = mo.md("**Доступ разрешен**") if is_allowed else mo.md("**Доступ запрещен**")
except Exception as e:
status = mo.md(f"**Ошибка подключения к ОРА:** {e}")
statusЧто здесь происходит?
Этот пример демонстрирует, как легко интегрировать OPA в интерфейс на Marimo. Все политики (например, `admin` может всё, а `user` — только определённые ресурсы) хранятся отдельно в OPA и могут быть изменены без переписывания кода приложения.
Теперь представим более реальную задачу: мы строим дашборд для аналитики, который выполняет SQL-запросы к Trino — распределённому движку для работы с большими данными. В Trino доступ к таблицам, схемам и столбцам также можно регулировать через OPA. Таким образом, у нас возникает два уровня авторизации:
Эти два уровня могут обслуживаться разными экземплярами OPA или одним, но с разными пакетами политик. Например, в Marimo мы проверяем политику `app/authz/allow`, а в Trino — `trino/authz/allow`. Это даёт гибкость: политики для интерфейса и для данных могут управляться разными командами или обновляться независимо.
В нашем приложении Marimo после успешной проверки прав на доступ к разделу мы можем формировать SQL-запрос и отправлять его в Trino. При этом Trino, в свою очередь, проверит, имеет ли пользователь право читать запрашиваемые таблицы, используя свой OPA-агент. Если хотя бы один из агентов вернёт отказ, пользователь не получит данные.
Такая двухуровневая архитектура обеспечивает безопасность «в глубину» и позволяет тонко настраивать политики как на уровне интерфейса, так и на уровне сырых данных.
Настройка и поддержка политик OPA, особенно когда речь идёт о десятках таблиц, ролей и атрибутов, может стать сложной задачей. Требуется не только писать правила на Rego, но и поддерживать актуальность данных о пользователях и ресурсах. Для упрощения этой работы существует проект Moat (Data Control Plane для Trino и OPA).
Moat предоставляет: https://github.com/moat-io/moat
Moat сам не принимает решений в рантайме — он лишь поставляет OPA необходимую информацию (политики и данные). Это позволяет удобно управлять множеством кластеров Trino и эфемерных окружений, добавляя OPA-контейнер в каждый координатор и указывая ему на Moat как источник бандлов.
Однако подробное рассмотрение Moat выходит за рамки этой статьи. Мы обязательно вернёмся к нему в отдельном материале, где разберём его архитектуру, настройку и примеры использования.
Связка Marimo и OPA даёт разработчикам дашбордов мощный и гибкий инструмент для управления доступом. Вы можете отделить политики от кода, упростить их изменение и аудит, а также комбинировать несколько OPA-агентов для разных уровней — приложения и данных. В сочетании с Trino и такими инструментами, как Moat, эта экосистема становится полноценным решением для корпоративных аналитических платформ.
Попробуйте предложенный пример в своём проекте — и вы убедитесь, как легко внедрить централизованное управление доступом, не усложняя код приложения. А о Moat мы расскажем в следующий раз!
Прощай уточка …
Еще пост про это https://habr.com/ru/amp/publications/1077408/
страница 203. «Encyclopaedia of Religion and Ethics» (том 3) народ Киссама
“Among the Kissama a debtor or criminal is eaten as a punishment” (Hamilton, JAI i. 187)
В этом же разделе (на той же странице 203) упоминается похожий обычай у другого африканского народа — Ба-Нгала (Ba-Ngala)
“the Ba-Ngala occasionally eat debtors” (Coguilhat, Sur le Haut-Congo, 1888, p. 337).
Так что делать то? По-шумерски разобраться или по-Киссамски, или по-Ba-Ngala в винном соусе?))
Чаще всего самой дорогостоящей ошибкой руководителя становится не провальная стратегия или нехватка финансирования, а эмоциональная незрелость. Бизнес — это стрессовая среда по определению. И именно в момент пикового напряжения лидер распаковывает свой истинный «уровень прошивки». Если внутри сидит подросток, он примет решение за 1 секунду. Если внутри взрослый — он выдержит паузу в 6 секунд.
Почему именно 6? Это время, необходимое мозгу, чтобы «выключить» миндалевидное тело (центр страха и агрессии) и передать управление префронтальной коре (центр логики). Большинство провалов случается именно в этот промежуток.
Вот шесть привычек, которые отличают хорошего лидера от «руководителя-подростка». Проверьте себя: если хотя бы три пункта — про вас, вы все еще играете в менеджмент, а не управляете им.
1. Привычка не защищаться в ответ на обратную связь
Подросток слышит критику и сразу ищет виноватого на стороне или объясняет, «почему так вышло». Зрелый руководитель в свои 6 секунд тишины просто говорит: *«Спасибо, я подумаю над этим»*. Он не обесценивает боль собеседника своей защитой. Помните: ваша репутация строится не на том, как вы правы, а на том, как вы принимаете правду о себе.
2. Привычка не перебивать
Для «руководителя-подростка» пауза в разговоре — это угроза, вакуум, который надо срочно заполнить своим голосом. Для лидера — это ресурс. Когда подчиненный замолкает, чтобы собраться с мыслями, а вы вставляете «Я понял, давай ближе к делу», вы убиваете инициативу. Научитесь считать до шести, прежде чем открыть рот. Часто в эти секунды собеседник сам приходит к нужному решению, и вам не придется отдавать приказы.
3. Привычка не отвечать на провокации сарказмом
Острые фразы — самый дешевый способ казаться умным. Подросток в кресле директора использует иронию, чтобы унизить оппонента в споре. Но в бизнесе сарказм — это маркер бессилия. Если вас задели, сделайте вдох, выдох и спросите: *«Что именно вас сейчас тревожит?»*. Это обезоруживает любую агрессию лучше, чем остроумная колкость.
4. Привычка не демонстрировать «героическое» терпение
Это ловушка для тех, кто прочитал слишком много книг по эмоциональному интеллекту. Подросток думает: «Я взрослый, я стерплю», накапливая раздражение месяцами. А затем взрывается из-за мелочи. Зрелый лидер не копит. Он говорит о дискомфорте в моменте, но ровным тоном. Те самые 6 секунд тишины нужны ему, чтобы отделить факт («срок сорван») от эмоции («меня не уважают») и озвучить только факт.
5. Привычка не использовать слово «Я» в кризис
Послушайте себя на планерке. Подросток говорит: *«Я не понимаю, как так вышло», «Я разочарован», «Я считаю, что вы...»*. Взрослый говорит: *«Ситуация требует изменений», «Результат не соответствует стандартам», «Какие шаги мы предпримем?»*. Смещение фокуса с собственных переживаний на объективную реальность — главный признак сепарации от должности.
6. Привычка завершать диалог, а не «оставлять последнее слово»
Это самый сложный пункт. Подросток обязан доказать, что он главнее, поэтому в конце любого разговора он добавляет веское заключение. Даже когда вопрос исчерпан. Зрелый лидер знает: тишина после договоренности — это печать. Если вы уже приняли решение, заткнитесь. Дайте ему «полежать». Ваши дополнительные 30 секунд нотаций разрушат все то доверие, которое вы построили за месяц.
суть:
Эта статья не про мягкость, а про саморегуляцию. Рынок не прощает истерик. «Руководитель-подросток» управляет людьми, чтобы казаться значимым. Лидер управляет людьми, чтобы они становились значимыми. И начинается это различие с малого — с умения промолчать те самые 6 секунд, когда внутри все кипит.
В следующий раз, когда вас захлестнет гнев или желание все контролировать, закройте рот и включите секундомер в голове. Скорее всего, через 6 секунд вы поймете, что ваш первоначальный ответ был бы катастрофой. А если нет — вы всегда успеете его сказать. Но теперь это будет выбор, а не рефлекс.
Аналитический ландшафт стремительно меняется. Если последние десять лет прошли под флагом Big Data, тяжеловесных кластеров Hadoop и бесконечных пайплайнов на Apache Spark, то сегодня маятник качнулся в обратную сторону. Наступила эпоха Small Data и встраиваемой аналитики (Embedded OLAP).
Основываясь на свежем выпуске дайджеста DuckDB Ecosystem Monthly #43 (июль 2026) собрали главные новости экосистемы. Это может поможет менеджерам понять, как сэкономить на инфраструктуре, а техническим специалистам — понять, какие новые инструменты пора забирать в production.
Встраиваемая аналитика убирает главное препятствие — сложность. Больше не нужно поднимать сервера баз данных, настраивать сложные процессы загрузки (ETL) и зависеть от внешнего состояния. Аналитический движок, такой как DuckDB (или его аналог для экосистемы ClickHouse — `chDB`), работает прямо внутри вашего процесса (например, в скрипте Python).
Для российского рынка, исторически любящего мощные решения вроде ClickHouse или Greenplum, это смена парадигмы. Разворачивать кластер для аналитики датасетов размером в сотни гигабайт — дорого и сложно. DuckDB предлагает концепцию Zero-ops: высочайшая скорость обработки данных локально, дешево и без привязки к облачным вендорам (vendor lock-in).
| Характеристика | Традиционные DWH | Встраиваемый OLAP (DuckDB) |
| Архитектура | Клиент-серверная, кластеры | Встраиваемая (внутри хост-процесса) |
| Инфраструктура | Требует команды DataOps / DevOps | Не требует поддержки серверов |
| Стоимость | Оплата за сервера 24/7 | Эфемерные вычисления (запускаются по требованию) |
Дайджест приводит примеры того, как крупные компании режут косты, меняя классические решения на DuckDB.
Известная платформа продуктовой аналитики PostHog перестроила архитектуру, отказавшись от мульти-тенантного кластера ClickHouse в пользу выделенных single-tenant инстансов DuckDB.
ClickHouse великолепен для быстрых аналитических запросов, но команде не хватало гибкости в моделировании данных и оптимизатора запросов на основе стоимости (cost-based optimizer). Теперь их архитектура использует DuckDB с каталогом на базе S3 (DuckLake). Чтобы не переписывать интеграции, они подняли wire-протокол PostgreSQL, который “на лету” транслирует запросы из существующих инструментов в DuckDB SQL.
Международная корпорация Merck Group переводит свои тяжелые дата-пайплайны с Apache Spark на DuckDB. Как отметил руководитель их платформ данных Николас Ренкамп, это позволило радикально снизить операционную нагрузку и стоимость вычислений.
На конференции DuckCon #7 показали впечатляющий кейс: полноценное озеро данных (Lakehouse) на базе DuckLake развернуто на недорогих серверах Hetzner. Стоимость такого решения составляет менее €15 в месяц, что примерно в три раза дешевле аналогичной инфраструктуры в AWS.
Инженерия данных становится проще и ближе к локальной разработке:
* MotherDuck Flights для AI-агентов: Запущен `Flights` — нативный Python-рантайм для выполнения задач, созданный специально для AI-агентов. Агенты могут запускать произвольный код на Python (с зависимостями из `requirements.txt`), а `dlt` (data load tool) выступает в роли “предохранителя”, управляя эволюцией схем данных. Управление идет через SQL-функции: `call md_create_flight(...)`. Биллинг идет только за время работы (около 60 центов в час).
* Portable Analytics Stack: Разработчики собирают полноценный DWH из open-source компонентов. Схема выглядит так: `dlt` забирает данные -> кладет в Cloudflare R2 -> SQLMesh на базе DuckDB отвечает за трансформации -> CI/CD крутится в GitHub Actions. Результат тестируется локально одной командой:
uv run sqlmesh plan dev* Floe (Data Contracts): Новый рантайм на базе Polars для валидации данных перед загрузкой. Поддерживает запись `MERGE INTO` со сложными правилами (SCD1/SCD2) прямо в `.duckdb` или облако MotherDuck.
* Пространственный SQL в браузере: Сборка CereusDB компилирует гео-движок SedonaDB под WebAssembly. Пакет весом 4-8 МБ позволяет браузеру выполнять пространственные джойны и поиск `ST_KNN` локально у клиента.
* Duckrun для Delta Lake: Движок, который читает и пишет форматы Delta Lake (через библиотеку `delta-rs`). Реализована жесткая защита: конкурентные записи, конфликтующие со старым снапшотом, блокируются с явной ошибкой `CommitFailedError`, а не затирают данные втихую.
Новый клиент-серверный протокол DuckDB Quack меняет правила игры для удаленной работы с данными. Независимые тесты (pushdown mode) показывают, что сервер забирает вычисления на себя с минимальным оверхедом:
Затраты времени на аналитические агрегации:
Даже при удаленной работе по сети, связка с Quack стабильно обходит классический PostgreSQL (у которого alpha approx 0.60, и разрыв лишь увеличивается с ростом объемов данных.
Что показали на DuckCon #7 в Амстердаме:
* DuckDB 2.0 (релиз осенью): Появится тип данных `VARIANT` (быстрый JSON), поддержка триггеров и асинхронный I/O для стремительного чтения Parquet с сетевых хранилищ.
* Неожиданные партнерства:
* MariaDB начинает встраивать DuckDB в качестве своего storage-движка (и сравнивает результаты в бенчмарках с ClickHouse).
Текущие релизы (v1.5.4 и v1.4.5 LTS):
Команда выпустила сразу два патча. Исправлены баги с парсингом `VARIANT` и ошибки записи gzip. Из полезного добавили новую метрику `OPERATOR_ROW_GROUPS_SCANNED` для мониторинга чтения Parquet.
* Ai4 2026 (4 августа, Лас-Вегас) — панельная дискуссия о современном стеке данных для AI.
* dbt Summit (15 сентября, Лас-Вегас) — слет дата-инженеров (более 2200 участников).
* Big Data London (23 сентября, Лондон) — один из крупнейших европейских дата-ивентов.
Heltec mesh pocket
Конект хороший, для иос приложение socialmesh не официальное, но работает.
Прошивку обновить проще простого, как файл на флешку записать.
+ Памятник зенитчикам