Улучшения домашки

This commit is contained in:
2025-12-21 21:09:52 +03:00
parent a347988af2
commit 20ea175e3a
2 changed files with 71 additions and 6 deletions
@@ -76,11 +76,44 @@ customer_id,status,event_ts,_load_id,load_ts
### 3.1. STG: загрузка CSV
1. Откройте `psql` в контейнере (см. инструкцию в `postgres-bookings/README.md`).
2. Загрузите файл `customer_status_events.csv` в таблицу `stg.customer_status_raw`:
- можно использовать `\copy` из `psql`;
- либо любой другой способ, к которому вы привыкли.
3. Убедитесь, что данные загрузились:
Есть два варианта — выберите любой. Для первого прохождения рекомендуем **вариант A** (самый простой).
#### Вариант A (рекомендуемый): вставить данные в STG через `INSERT`
Откройте SQL‑клиент (DBeaver или `psql`) и вставьте данные текстом:
> 💡 Если вы уже загружали данные в `stg.customer_status_raw` и делаете повторный запуск — начните с `TRUNCATE stg.customer_status_raw;`.
>
> 💡 В примере ниже показан минимальный набор для клиента 101. Чтобы получить несколько клиентов и больше событий — используйте вариант B (CSV) или добавьте строки из файла `dwh-modeling/data/customer_status_events.csv`.
```sql
INSERT INTO stg.customer_status_raw (customer_id, status, event_ts, _load_id, _load_ts) VALUES
('101','new','2024-01-01 09:00:00','batch_20240101_1000','2024-01-01 10:00:00'),
('101','active','2024-02-15 10:30:00','batch_20240215_1100','2024-02-15 11:00:00'),
('101','vip','2024-05-10 11:00:00','batch_20240510_1200','2024-05-10 12:00:00'),
('101','churned','2024-09-01 12:15:00','batch_20240901_1300','2024-09-01 13:00:00');
```
> 💡 Здесь `_load_ts` — это время загрузки (в CSV оно называется `load_ts`).
#### Вариант B: загрузить CSV
Можно загрузить файл `dwh-modeling/data/customer_status_events.csv` в таблицу `stg.customer_status_raw`:
- **Через DBeaver**: Import Data → CSV → `stg.customer_status_raw` (колонку `load_ts` маппить в `_load_ts`).
- **Через `psql` в контейнере (`./psql_sh`)**: без установки `psql` на хост.
Способ: передайте CSV в `psql` через STDIN и выполните `\copy ... FROM STDIN`:
```bash
./postgres-bookings/psql_sh -c "TRUNCATE stg.customer_status_raw;"
cat dwh-modeling/data/customer_status_events.csv | ./postgres-bookings/psql_sh -c \
"\\copy stg.customer_status_raw(customer_id,status,event_ts,_load_id,_load_ts) FROM STDIN WITH (FORMAT csv, HEADER true)"
```
> 💡 Для части 5 (инкрементальная загрузка) `TRUNCATE stg.customer_status_raw` делать не нужно — загружайте только новые строки.
После загрузки убедитесь, что данные на месте:
```sql
SELECT * FROM stg.customer_status_raw LIMIT 10;
@@ -97,6 +130,8 @@ SELECT * FROM stg.customer_status_raw LIMIT 10;
- аккуратно обработать возможные пустые значения (если бы они были);
- заполнить `_load_id` и `_load_ts` в `ods.customer_status`.
> 💡 Для простоты сделайте загрузку идемпотентной через `TRUNCATE ods.customer_status;` перед `INSERT` (таблица в ODS имеет первичный ключ `(customer_id, event_ts)`).
Проверьте, что в `ods.customer_status` данные выглядят аккуратно:
```sql
@@ -135,8 +170,15 @@ ORDER BY customer_id, event_ts;
- `valid_from``event_ts::date`,
- `valid_to` — следующий `event_ts::date` (а у последней версии `valid_to = NULL`).
> 💡 Упрощение для домашки: считаем, что у клиента не бывает двух разных смен статуса в один и тот же день.
> Если такое бывает — удобнее строить периоды в `TIMESTAMP` (или вводить дополнительное правило сортировки), но это уже усложнение.
> 💡 Если в событиях встречаются повторы одного и того же статуса подряд, можно отфильтровать “не-изменения” через `LAG(status)` (или `LAG(hashdiff)`) перед расчётом `LEAD()`.
3. Вставьте получившиеся строки в `dds.dim_customer_status`. Актуальная строка для клиента — та, где `valid_to IS NULL`.
> 💡 Для первой версии решения можно сделать full refresh: перед вставкой очистить таблицу (`TRUNCATE dds.dim_customer_status;`), как в основном примере с `dds.dim_customer`.
```sql
INSERT INTO dds.dim_customer_status (
customer_bk, status, hashdiff,
@@ -192,6 +234,11 @@ ORDER BY customer_bk, valid_from;
Опциональное задание для закрепления: собрать небольшую витрину с количеством клиентов по статусам на каждую дату.
Перед началом убедитесь, что слой DM создан (схема `dm` и таблицы):
- выполните `dwh-modeling/sql/05_ddl_dm.sql` (один раз);
- затем можно собирать витрину.
Пример целевой таблицы:
```sql
+19 -1
View File
@@ -1,2 +1,20 @@
#!/bin/bash
docker compose exec -it db psql -U ${POSTGRES_USER:-postgres} -d demo
set -euo pipefail
# Usage:
# ./psql_sh # interactive psql inside container
# ./psql_sh -c "SELECT 1;" # run a command
# cat file.csv | ./psql_sh -c "\\copy ... FROM STDIN WITH (FORMAT csv, HEADER true)"
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
compose_file="${script_dir}/docker-compose.yml"
compose() {
docker compose -f "${compose_file}" --project-directory "${script_dir}" "$@"
}
if [ -t 0 ]; then
compose exec -it db psql -U "${POSTGRES_USER:-postgres}" -d demo "$@"
else
compose exec -T db psql -U "${POSTGRES_USER:-postgres}" -d demo "$@"
fi