feat(ddl): пояс назван явно — в типах колонок и в разборе строки
- Зачем: - конвенция #63 записана, а код её не достиг: колонки времени стояли без пояса, и сходилось всё лишь потому, что пояс сервера — UTC. - Что: - UTCEventTime объявлен DateTime('UTC'), служебные метки _load_ts и kafka_timestamp — DateTime64(3, 'UTC') в STG и ODS. - parseDateTimeOrNull получил третьим аргументом 'UTC': маска сверяет суффикс Z как букву, зоны из строки не берёт вовсе. - контракт схемы и описание выгрузки несут тип с поясом; имя пояса Europe/Samara встало рядом со смещением в world.py, сходимость сверяет тест. - учебный комментарий о линзе — у первой колонки с явным поясом. - Проверка: - make lint, make typecheck, make test (408 тестов) - make clean && make up && make check-clickhouse — 9 из 9 - замер тикета повторён: под session_timezone='Europe/Samara' колонка показана 2026-05-31 23:37:00, как и без настроек Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -45,10 +45,18 @@ SETTINGS
|
||||
-- колонки _timestamp_ms, а не из _timestamp. Измерено на стенде 5 августа
|
||||
-- 2026 года: _timestamp — Nullable(DateTime), то есть секунды; _timestamp_ms —
|
||||
-- Nullable(DateTime64(3)). Взяты миллисекунды: у брокера метка миллисекундная,
|
||||
-- _load_ts рядом тоже DateTime64(3), а слой сырья хранит то, что приехало, и
|
||||
-- _load_ts рядом тоже миллисекундная, а слой сырья хранит то, что приехало, и
|
||||
-- округлять ему нечего. Обнуляемость обязательна: метку брокер заполняет не
|
||||
-- всегда, а необнуляемый тип дал бы либо падение приёма, либо тихий 1970 год.
|
||||
--
|
||||
-- Пояс у обеих меток написан в типе — DateTime64(3, 'UTC'); в DDL стенда он
|
||||
-- встречается здесь впервые. Само число от пояса не зависит, это секунды от
|
||||
-- начала эпохи. Пояс — линза: по нему решают, какие часы покажут метку и в
|
||||
-- какие сутки она попадёт, то есть чем окажется toDate(_load_ts) в ключе
|
||||
-- партиции ниже. Не назови линзу — её выберет пояс сервера, умолчание, которого
|
||||
-- в коде не видно. Правило целиком — docs/architecture/storage.md, «Часовые
|
||||
-- пояса».
|
||||
--
|
||||
-- Нарезка и срок жизни — по _load_ts, то есть по реальному времени загрузки:
|
||||
-- модельный день события живёт в ODS, а по нему TTL был бы просто сломан.
|
||||
-- Срок — трое суток плюс хвост до суток: куски снимаются целиком
|
||||
@@ -64,9 +72,9 @@ CREATE TABLE IF NOT EXISTS stg.hits_raw_rep ON CLUSTER clickstream_cluster
|
||||
kafka_topic LowCardinality(String),
|
||||
kafka_partition UInt64,
|
||||
kafka_offset UInt64,
|
||||
kafka_timestamp Nullable(DateTime64(3)),
|
||||
kafka_timestamp Nullable(DateTime64(3, 'UTC')),
|
||||
consumer_host LowCardinality(String),
|
||||
_load_ts DateTime64(3)
|
||||
_load_ts DateTime64(3, 'UTC')
|
||||
)
|
||||
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/{database}/{table}', '{replica}')
|
||||
PARTITION BY toDate(_load_ts)
|
||||
|
||||
Reference in New Issue
Block a user