From 3ffce6387ea357362caf4a7bc24b1e155150e4b2 Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Sun, 30 Aug 2026 18:42:01 -0400 Subject: [PATCH] =?UTF-8?q?feat(superset):=20=D0=B4=D0=B0=D1=82=D0=B0?= =?UTF-8?q?=D1=81=D0=B5=D1=82=D1=8B=20=D0=B8=20=D0=B4=D0=B0=D1=88=D0=B1?= =?UTF-8?q?=D0=BE=D1=80=D0=B4=20=C2=AB=D0=91=D0=B8=D0=B7=D0=BD=D0=B5=D1=81?= =?UTF-8?q?-=D1=81=D1=8E=D0=B6=D0=B5=D1=82=D1=8B=C2=BB=20=D0=B4=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D0=B2=D0=BE=D0=BC=20=D0=B8=D0=BC=D0=BF=D0=BE=D1=80?= =?UTF-8?q?=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - этап 8 (#196): три сюжета спеки — выручка, сверка, посетители / известные — должны приезжать в Superset при каждой инициализации стенда, без ручной сборки в интерфейсе. - Что: - дерево infra/superset/import/ дополнено датасетами трех витрин dm, тремя графиками и дашбордом «Бизнес-сюжеты»; uuid розданы рукой, русские строки читаемы, metadata.yaml сокращен до версии формата. - написан справочник docs/architecture/superset.md: устройство зоны, дерево импорта, маршрут свежего экспорта, ловушки импорта. - в docs/architecture/dm.md добавлена ссылка на справочник зоны. - Проверка: - docker compose run --rm superset-init — импорт начисто, затем три графика отдают данные через API (54/48/10 строк). - прогон рецепта «чистая установка» из справочника: сброс базы superset в postgres-metadata, импорт, активы на месте. - make lint и make check-services зеленые (7/7). Co-Authored-By: Claude Fable 5 --- docs/architecture/dm.md | 3 +- docs/architecture/superset.md | 159 ++++++++++++++++++ .../import/charts/purchase_vs_orders.yaml | 31 ++++ .../charts/revenue_by_day_and_category.yaml | 30 ++++ .../charts/visitors_and_known_users.yaml | 29 ++++ .../import/dashboards/business_stories.yaml | 105 ++++++++++++ .../datasets/ClickHouse/daily_traffic_v.yaml | 106 ++++++++++++ .../ClickHouse/purchase_vs_orders_v.yaml | 136 +++++++++++++++ .../datasets/ClickHouse/revenue_daily_v.yaml | 138 +++++++++++++++ infra/superset/import/metadata.yaml | 2 - 10 files changed, 736 insertions(+), 3 deletions(-) create mode 100644 docs/architecture/superset.md create mode 100644 infra/superset/import/charts/purchase_vs_orders.yaml create mode 100644 infra/superset/import/charts/revenue_by_day_and_category.yaml create mode 100644 infra/superset/import/charts/visitors_and_known_users.yaml create mode 100644 infra/superset/import/dashboards/business_stories.yaml create mode 100644 infra/superset/import/datasets/ClickHouse/daily_traffic_v.yaml create mode 100644 infra/superset/import/datasets/ClickHouse/purchase_vs_orders_v.yaml create mode 100644 infra/superset/import/datasets/ClickHouse/revenue_daily_v.yaml diff --git a/docs/architecture/dm.md b/docs/architecture/dm.md index b2aed93..3f9a9e2 100644 --- a/docs/architecture/dm.md +++ b/docs/architecture/dm.md @@ -47,7 +47,8 @@ Дашборд этапа 8 стоит только на витринах стенда: приёмка этапа не зависит от выполненных домашек. Расширение дашборда визуализациями по своим -витринам — отдельная домашка после этапа 8. +витринам — отдельная домашка после этапа 8. Устройство самого дашборда — в +[доке зоны Superset](superset.md). ## Ритм пересборки diff --git a/docs/architecture/superset.md b/docs/architecture/superset.md new file mode 100644 index 0000000..b182e7d --- /dev/null +++ b/docs/architecture/superset.md @@ -0,0 +1,159 @@ +# Superset: витрины глазами + +Документ описывает зону BI: куда Superset ходит за данными и за своими +метаданными, из чего собран стендовый дашборд, как снять свежий экспорт после +правки в интерфейсе и почему правка руками живет только до перезапуска. + +Состав сюжетов и колонок витрин здесь не повторяется: он живет в +[спеке](../specs/2026-07-30-stand-v2-realism.md), раздел 7, и в +[доке слоя DM](dm.md). + +## Устройство зоны + +Superset читает ClickHouse пользователем `bi` **на ноде 2** — так задано +подключением `ClickHouse` (`clickhousedb://bi@clickhouse-02:8123`). Нода 2 +здесь — ловушка правильных ошибок из +[спеки](../specs/2026-07-30-stand-v2-realism.md), раздел «Роли нод»: DDL идет +с ноды 1, и забытый `ON CLUSTER` виден в дашборде. + +Пароля в подключении нет. Его отдает штатное хранилище паролей Superset +(`SQLALCHEMY_CUSTOM_PASSWORD_STORE` в `infra/superset/superset_config.py`), +которое читает `CLICKHOUSE_BI_PASSWORD` из окружения. Поэтому файл подключения +безопасно лежит в git, и экспорт из интерфейса не должен возвращать пароль +обратно в YAML. + +Свои метаданные — подключения, датасеты, графики, дашборды, пользователи — +Superset держит в базе `superset` служебного `postgres-metadata`, рядом с базой +Airflow. В ClickHouse он не пишет ничего. + +## Дерево импорта + +`infra/superset/import/` — это дашборд стенда в виде файлов. Каталог +смонтирован в контейнер как `/app/import`. + +| Файл | Что описывает | +|---|---| +| `metadata.yaml` | версия формата, `1.0.0`; больше в нем ничего нет | +| `databases/clickhouse.yaml` | подключение к ClickHouse: URI без пароля и постоянный uuid | +| `datasets/ClickHouse/*.yaml` | три витрины: `revenue_daily_v`, `purchase_vs_orders_v`, `daily_traffic_v` | +| `charts/*.yaml` | три графика: столбики выручки, сводная таблица сверки, линии трафика | +| `dashboards/business_stories.yaml` | дашборд «Бизнес-сюжеты» и раскладка панелей | + +Связаны файлы не путями, а uuid. Датасет называет `database_uuid`, график — +`dataset_uuid`, а дашборд не называет графики вовсе: единственная связь с ними +лежит в его `position`, где узел `CHART-*` несет `meta.uuid` нужного графика. +График, которого нет в `position`, импортируется молча и не появляется нигде. + +Uuid у стенда розданы рукой: общее начало +`19600000-0000-4000-8000-`, дальше номер объекта в последнем блоке — `1`–`3` +у датасетов, `101`–`103` у графиков, `201` у дашборда +(`…-000000000101`). Экспорт из интерфейса приносит свои, сгенерированные; +их заменяют на эти, иначе повторный импорт заведет вторую копию объекта вместо +обновления первой. + +Датасет несет русские имена колонок, формат денег и метрику — а график только +ссылается на них по имени. Значит, подпись или формат правятся в одном месте, а +не в каждом графике. + +Датасеты объявлены физическими (`schema: dm`, `sql: null`), хотя за именем стоит +представление ClickHouse. Импорт в источник не ходит и разницы между таблицей и +представлением не знает, а виртуальный датасет со своим SQL просто повторил бы +запрос, который уже живет в `sql/ddl/60-dm-views.sql`. + +## Импорт при каждой инициализации + +Последняя строка `infra/superset/init.sh`: + +``` +superset import-directory /app/import --overwrite +``` + +Служба `superset-init` отрабатывает перед подъемом самого Superset, то есть при +каждом `make up`. Без `--overwrite` второй прогон падал бы на первом же +знакомом uuid; с ним объект обновляется на месте, и повторная инициализация +проходит без ошибок. + +Отсюда правило зоны: **стендовый дашборд не расширяют руками в интерфейсе.** +Правка живет до следующей инициализации, а потом молча заменяется тем, что +лежит в git. Пробовать интерфейс менти никто не мешает — но все, что должно +пережить перезапуск, приезжает файлом. + +## Как снять свежий экспорт + +Маршрут один: правишь на живом стенде, забираешь экспорт, кладешь дерево в git. + +1. Собрать или поправить график и дашборд в интерфейсе — на стенде, а не в + файлах. Ключи `params` графиков велики, недокументированы и меняются от + версии к версии; неверный ключ не ошибается, а рисует пустоту. Интерфейс + здесь единственный надежный оракул. +2. Снять экспорт и достать его из контейнера: + + ``` + docker compose exec superset superset export-dashboards -f /tmp/export.zip + docker compose cp superset:/tmp/export.zip /tmp/export.zip + unzip -d /tmp/superset-export /tmp/export.zip + ``` + + Внутри архива — один каталог `dashboard_export_<дата>` ровно той же формы, + что и дерево импорта. Команда выгружает все дашборды сразу; на стенде он + один. +3. Вычистить экспортный сор перед коммитом: + - выбросить экспортный `databases/` — наш `clickhouse.yaml` остается как + есть, с постоянным uuid и без пароля; + - оставить в `metadata.yaml` одну строку `version: 1.0.0`; + - убрать из графиков `params.datasource`, `params.slice_id` и + `params.dashboards` — это идентификаторы строк того Superset, где + снимали, а импорт выводит связи из uuid; + - убрать `query_context` — снимок запроса оттуда же. Импорт его не + требует и обратно не заполняет: после переимпорта он остается пустым, на + отрисовку это не влияет; + - перезаписать русские строки читаемыми. Экспорт кодирует их + `\uXXXX`-последовательностями, и после каждого круга их приходится + раскодировать заново: имена графиков и подписи колонок читает менти, и в + файле, и в диффе. Годится любой повторный дамп YAML с + `allow_unicode=True`; + - вернуть постоянные uuid из схемы выше. +4. Скопировать вычищенное дерево в `infra/superset/import/` и проверить + импортом **на пустых метаданных** — иначе прогон проверит только обновление + уже стоящих объектов, а молчаливый пропуск нового спрячется за старым. + Активы Superset лежат в базе `superset` службы `postgres-metadata`, поэтому + адресный сброс — эта база: + + ``` + docker compose stop superset + docker compose exec postgres-metadata sh -c \ + 'psql -U "$POSTGRES_USER" -d postgres \ + -c "DROP DATABASE superset WITH (FORCE)" \ + -c "CREATE DATABASE superset OWNER \"$SUPERSET_METADATA_USER\""' + docker compose run --rm superset-init + docker compose up -d superset + ``` + + Базу приходится создавать тут же: скрипт `infra/postgres/init/` заводит ее + один раз, при первой инициализации тома Postgres. `make rebuild-storage` + для этой проверки не годится — он гоняет `world_recreate` в ClickHouse и + метаданных Superset не касается. `make clean` сбросит и их, но заодно снесет + весь стенд, включая метаданные Airflow в той же службе. + + После импорта дашборд смотрят глазами: это единственное доказательство — + см. ловушку ниже. + +## Ловушки + +**Импорт молчит.** График, чей `dataset_uuid` не разрешился, отбрасывается без +единого слова; дашборд, у которого не сошлись ссылки на графики, +пропускается. Ошибки уходят в журнал, и `init.sh` +завершается нулем в любом случае. Поэтому импорт проверяют глазами или +запросом к API — но не тем, что команда отработала. + +**`--overwrite` синхронизирует датасет разрушительно.** Колонки и метрики +берутся из YAML целиком: добавленная в интерфейсе метрика или подпись колонки +исчезнет при следующем старте контейнера. Правка датасета — это правка файла. + +## Что проверяет стенд + +`make check-services` входит в Superset, находит подключение `ClickHouse`, +сверяет его uuid и безопасный URI и требует схему `dm` — то есть подтверждает +живое подключение и хранилище пароля. Сами графики и дашборд ни одна цель не +проверяет: их смотрят глазами после переинициализации. Полная карта целей — в +[доке проверок](testing.md). diff --git a/infra/superset/import/charts/purchase_vs_orders.yaml b/infra/superset/import/charts/purchase_vs_orders.yaml new file mode 100644 index 0000000..a6bdc34 --- /dev/null +++ b/infra/superset/import/charts/purchase_vs_orders.yaml @@ -0,0 +1,31 @@ +slice_name: Сверка purchase и заказов +description: null +certified_by: null +certification_details: null +viz_type: pivot_table_v2 +params: + viz_type: pivot_table_v2 + groupbyRows: + - order_day + groupbyColumns: + - mismatch_class + metrics: + - order_count + adhoc_filters: + - expressionType: SIMPLE + subject: order_day + operator: TEMPORAL_RANGE + comparator: No filter + clause: WHERE + aggregateFunction: Sum + metricsLayout: COLUMNS + rowOrder: key_a_to_z + colOrder: key_a_to_z + order_desc: true + row_limit: 10000 + valueFormat: SMART_NUMBER + date_format: smart_date +cache_timeout: null +uuid: 19600000-0000-4000-8000-000000000102 +version: 1.0.0 +dataset_uuid: 19600000-0000-4000-8000-000000000002 diff --git a/infra/superset/import/charts/revenue_by_day_and_category.yaml b/infra/superset/import/charts/revenue_by_day_and_category.yaml new file mode 100644 index 0000000..c7351a6 --- /dev/null +++ b/infra/superset/import/charts/revenue_by_day_and_category.yaml @@ -0,0 +1,30 @@ +slice_name: Выручка по дням и категориям +description: null +certified_by: null +certification_details: null +viz_type: echarts_timeseries_bar +params: + viz_type: echarts_timeseries_bar + x_axis: report_date + metrics: + - revenue + groupby: + - product_category + adhoc_filters: + - expressionType: SIMPLE + subject: report_date + operator: TEMPORAL_RANGE + comparator: No filter + clause: WHERE + row_limit: 10000 + stack: Stack + orientation: vertical + show_legend: true + rich_tooltip: true + show_value: false + y_axis_format: ',.2f' + x_axis_time_format: smart_date +cache_timeout: null +uuid: 19600000-0000-4000-8000-000000000101 +version: 1.0.0 +dataset_uuid: 19600000-0000-4000-8000-000000000001 diff --git a/infra/superset/import/charts/visitors_and_known_users.yaml b/infra/superset/import/charts/visitors_and_known_users.yaml new file mode 100644 index 0000000..e0c06f3 --- /dev/null +++ b/infra/superset/import/charts/visitors_and_known_users.yaml @@ -0,0 +1,29 @@ +slice_name: Посетители и известные пользователи +description: null +certified_by: null +certification_details: null +viz_type: echarts_timeseries_line +params: + viz_type: echarts_timeseries_line + x_axis: report_date + metrics: + - visitors + - known_users + groupby: [] + adhoc_filters: + - expressionType: SIMPLE + subject: report_date + operator: TEMPORAL_RANGE + comparator: No filter + clause: WHERE + row_limit: 10000 + seriesType: echarts_timeseries_line + show_legend: true + rich_tooltip: true + show_value: false + y_axis_format: ',d' + x_axis_time_format: smart_date +cache_timeout: null +uuid: 19600000-0000-4000-8000-000000000103 +version: 1.0.0 +dataset_uuid: 19600000-0000-4000-8000-000000000003 diff --git a/infra/superset/import/dashboards/business_stories.yaml b/infra/superset/import/dashboards/business_stories.yaml new file mode 100644 index 0000000..f7b17c5 --- /dev/null +++ b/infra/superset/import/dashboards/business_stories.yaml @@ -0,0 +1,105 @@ +dashboard_title: Бизнес-сюжеты +description: null +css: null +slug: business-stories +certified_by: null +certification_details: null +published: true +uuid: 19600000-0000-4000-8000-000000000201 +position: + DASHBOARD_VERSION_KEY: v2 + ROOT_ID: + id: ROOT_ID + type: ROOT + children: + - GRID_ID + GRID_ID: + id: GRID_ID + type: GRID + parents: + - ROOT_ID + children: + - ROW-revenue + - ROW-pvo + - ROW-traffic + ROW-revenue: + id: ROW-revenue + type: ROW + parents: + - ROOT_ID + - GRID_ID + children: + - CHART-revenue + meta: + background: BACKGROUND_TRANSPARENT + CHART-revenue: + id: CHART-revenue + type: CHART + parents: + - ROOT_ID + - GRID_ID + - ROW-revenue + children: [] + meta: + chartId: 1 + height: 50 + width: 12 + sliceName: Выручка по дням и категориям + uuid: 19600000-0000-4000-8000-000000000101 + ROW-pvo: + id: ROW-pvo + type: ROW + parents: + - ROOT_ID + - GRID_ID + children: + - CHART-pvo + meta: + background: BACKGROUND_TRANSPARENT + CHART-pvo: + id: CHART-pvo + type: CHART + parents: + - ROOT_ID + - GRID_ID + - ROW-pvo + children: [] + meta: + chartId: 2 + height: 50 + width: 12 + sliceName: Сверка purchase и заказов + uuid: 19600000-0000-4000-8000-000000000102 + ROW-traffic: + id: ROW-traffic + type: ROW + parents: + - ROOT_ID + - GRID_ID + children: + - CHART-traffic + meta: + background: BACKGROUND_TRANSPARENT + CHART-traffic: + id: CHART-traffic + type: CHART + parents: + - ROOT_ID + - GRID_ID + - ROW-traffic + children: [] + meta: + chartId: 3 + height: 50 + width: 12 + sliceName: Посетители и известные пользователи + uuid: 19600000-0000-4000-8000-000000000103 +metadata: + color_scheme: supersetColors + cross_filters_enabled: false + chart_configuration: {} + expanded_slices: {} + default_filters: '{}' + native_filter_configuration: [] +theme_uuid: null +version: 1.0.0 diff --git a/infra/superset/import/datasets/ClickHouse/daily_traffic_v.yaml b/infra/superset/import/datasets/ClickHouse/daily_traffic_v.yaml new file mode 100644 index 0000000..082a323 --- /dev/null +++ b/infra/superset/import/datasets/ClickHouse/daily_traffic_v.yaml @@ -0,0 +1,106 @@ +table_name: daily_traffic_v +main_dttm_col: report_date +currency_code_column: null +description: null +default_endpoint: null +offset: 0 +cache_timeout: null +catalog: null +schema: dm +sql: null +params: null +template_params: null +filter_select_enabled: true +fetch_values_predicate: null +extra: null +normalize_columns: false +always_filter_main_dttm: false +folders: null +uuid: 19600000-0000-4000-8000-000000000003 +metrics: +- metric_name: known_users + verbose_name: Известные пользователи + metric_type: null + expression: SUM(known_users) + description: null + d3format: ',d' + currency: null + extra: null + warning_text: null +- metric_name: visitors + verbose_name: Посетители + metric_type: null + expression: SUM(visitors) + description: null + d3format: ',d' + currency: null + extra: null + warning_text: null +columns: +- column_name: _load_ts + verbose_name: Время загрузки + is_dttm: true + is_active: true + type: DATETIME64(3, 'UTC') + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: known_users + verbose_name: Известные пользователи + is_dttm: false + is_active: true + type: UINT64 + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: _load_id + verbose_name: Запуск загрузки + is_dttm: false + is_active: true + type: STRING + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: visitors + verbose_name: Посетители + is_dttm: false + is_active: true + type: UINT64 + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: report_date + verbose_name: Дата + is_dttm: true + is_active: true + type: DATE + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +version: 1.0.0 +database_uuid: 4b8f2c6e-1d3a-4f5b-9c7d-2e8a1f0b3c5d diff --git a/infra/superset/import/datasets/ClickHouse/purchase_vs_orders_v.yaml b/infra/superset/import/datasets/ClickHouse/purchase_vs_orders_v.yaml new file mode 100644 index 0000000..52cceab --- /dev/null +++ b/infra/superset/import/datasets/ClickHouse/purchase_vs_orders_v.yaml @@ -0,0 +1,136 @@ +table_name: purchase_vs_orders_v +main_dttm_col: order_day +currency_code_column: null +description: null +default_endpoint: null +offset: 0 +cache_timeout: null +catalog: null +schema: dm +sql: null +params: null +template_params: null +filter_select_enabled: true +fetch_values_predicate: null +extra: null +normalize_columns: false +always_filter_main_dttm: false +folders: null +uuid: 19600000-0000-4000-8000-000000000002 +metrics: +- metric_name: order_count + verbose_name: Количество заказов + metric_type: null + expression: COUNT(order_id) + description: null + d3format: ',d' + currency: null + extra: null + warning_text: null +columns: +- column_name: items_total + verbose_name: Сумма позиций заказа + is_dttm: false + is_active: true + type: NULLABLE(DECIMAL(18, 2)) + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: _load_ts + verbose_name: Время загрузки + is_dttm: true + is_active: true + type: DATETIME64(3, 'UTC') + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: declared_revenue + verbose_name: Выручка purchase + is_dttm: false + is_active: true + type: NULLABLE(DECIMAL(18, 2)) + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: status + verbose_name: Статус заказа + is_dttm: false + is_active: true + type: LOWCARDINALITY(NULLABLE(STRING)) + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: mismatch_class + verbose_name: Класс расхождения + is_dttm: false + is_active: true + type: LOWCARDINALITY(STRING) + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: order_day + verbose_name: День заказа + is_dttm: true + is_active: true + type: DATE + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: _load_id + verbose_name: Запуск загрузки + is_dttm: false + is_active: true + type: STRING + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: order_id + verbose_name: Заказ + is_dttm: false + is_active: true + type: STRING + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +version: 1.0.0 +database_uuid: 4b8f2c6e-1d3a-4f5b-9c7d-2e8a1f0b3c5d diff --git a/infra/superset/import/datasets/ClickHouse/revenue_daily_v.yaml b/infra/superset/import/datasets/ClickHouse/revenue_daily_v.yaml new file mode 100644 index 0000000..a463b33 --- /dev/null +++ b/infra/superset/import/datasets/ClickHouse/revenue_daily_v.yaml @@ -0,0 +1,138 @@ +table_name: revenue_daily_v +main_dttm_col: report_date +currency_code_column: null +description: null +default_endpoint: null +offset: 0 +cache_timeout: null +catalog: null +schema: dm +sql: null +params: null +template_params: null +filter_select_enabled: true +fetch_values_predicate: null +extra: null +normalize_columns: false +always_filter_main_dttm: false +folders: null +uuid: 19600000-0000-4000-8000-000000000001 +metrics: +- metric_name: revenue + verbose_name: Выручка + metric_type: null + expression: SUM(revenue) + description: null + d3format: ',.2f' + currency: + symbol: ₽ + symbolPosition: suffix + extra: null + warning_text: null +columns: +- column_name: _load_ts + verbose_name: Время загрузки + is_dttm: true + is_active: true + type: DATETIME64(3, 'UTC') + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: aov + verbose_name: Средний чек + is_dttm: false + is_active: true + type: DECIMAL(18, 2) + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: revenue + verbose_name: Выручка + is_dttm: false + is_active: true + type: DECIMAL(18, 2) + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: product_category + verbose_name: Категория товара + is_dttm: false + is_active: true + type: LOWCARDINALITY(STRING) + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: _load_id + verbose_name: Запуск загрузки + is_dttm: false + is_active: true + type: STRING + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: orders + verbose_name: Заказы + is_dttm: false + is_active: true + type: UINT64 + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: units + verbose_name: Товары + is_dttm: false + is_active: true + type: UINT64 + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +- column_name: report_date + verbose_name: Дата + is_dttm: true + is_active: true + type: DATE + advanced_data_type: null + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + datetime_format: null + extra: null +version: 1.0.0 +database_uuid: 4b8f2c6e-1d3a-4f5b-9c7d-2e8a1f0b3c5d diff --git a/infra/superset/import/metadata.yaml b/infra/superset/import/metadata.yaml index 33e419e..2ef3d52 100644 --- a/infra/superset/import/metadata.yaml +++ b/infra/superset/import/metadata.yaml @@ -1,3 +1 @@ version: 1.0.0 -type: Database -timestamp: '2026-07-30T00:00:00+00:00'