Seeds 与 SQL:让小商店数据进入数据库
目标:把两份 CSV 装载成 seed 表,并用 SQL 核对订单行数与金额单位。
上一课只有一个常量。现在引入贯穿课程的输入:四位客户、五笔订单。CSV 是逗号分隔的文本,第一行是列名。seed 是 dbt 项目中的小型静态 CSV,运行 dbt seed 后成为数据库表。它适合练习样本、国家代码等小型映射,不适合作为大型交易数据库的同步方案。
为了便于手算,我们约定每笔订单只有一个总金额。暂不处理多币种、部分退款和订单行项目。写模型之前要先确定这个范围,否则看起来正确的求和也可能表达另一种业务含义。
输入文件就是实验数据
在第 2 课的项目根目录中,创建 seeds/raw_customers.csv:
customer_id,customer_name
1,Ada
2,Bo
3,Chen
4,Dee
创建 seeds/raw_orders.csv:
order_id,customer_id,order_date,status,amount_cents,updated_at
101,1,2026-01-01,completed,1200,2026-01-01 10:00:00
102,1,2026-01-02,returned,800,2026-01-02 10:00:00
103,2,2026-01-02,completed,2500,2026-01-02 11:00:00
104,2,2026-01-03,completed,1500,2026-01-03 10:00:00
105,3,2026-01-03,placed,600,2026-01-03 11:00:00
order_date 表示下单日期;updated_at 表示业务记录最后修改时间,两者可以不同。客户 4 没有订单是刻意设计的边界情形。文件名中的 raw 表示“尚未整理的输入”。这些名字是教学约定,不是 dbt 的保留关键字。
先数 CSV 数据行,再运行:
uv run dbt seed --profiles-dir .
uv run dbt show --profiles-dir . --inline "select count(*) as order_count from {{ ref('raw_orders') }}"
预期输出的查询值为 order_count = 5。count(*) 数全部行,不把 CSV 表头算作数据。seed 表在此时已保存在数据库中;编辑 CSV 后,需要再次执行 seed 才会更新数据库里的样本。
读懂一条业务查询
下面是终端命令,SQL 已放在双引号内部,可以直接运行:
uv run dbt show --profiles-dir . --inline "select order_id, amount_cents / 100.0 as amount from {{ ref('raw_orders') }} where status = 'completed' order by order_id"
from 指定输入;where 保留符合条件的行;select 指定返回的列;order by 让预览顺序稳定。100.0 表达从分到元的换算。第 4 课会把展示金额转成固定两位的小数类型。
预期结果的数值为:
order_id | amount
101 | 12.0
103 | 25.0
104 | 15.0
102 是退货,105 仍在下单状态,所以不在结果中。三笔 completed 合计 52 元。后续报表应该与这项手算结果一致。
让修改真的进入数据库
- 把 CSV 中 105 的状态从 placed 改成 completed。
- 只运行上面的预览,观察它仍只有三行。文件与已加载的表不是同一份状态。
- 运行
uv run dbt seed --profiles-dir . --select raw_orders,再预览,应增加订单 105、金额 6.0。 - 把状态恢复成 placed,再运行同一个 seed 命令。本课之后统一使用原始五行数据。
独立练习:不改文件,查询 returned 订单的 order_id 和 amount_cents,并预测结果。不要在查询里把金额换成元,因为本题要核对输入单位。
参考答案
uv run dbt show --profiles-dir . --inline "select order_id, amount_cents from {{ ref('raw_orders') }} where status = 'returned' order by order_id"
应只有 102 | 800。金额 800 的单位仍然是分;列名包含单位,可以降低误用概率。
若出现 CSV 解析错误,检查每行是否恰有六列,是否误用了中文逗号;若显示旧数据,先确认已保存 CSV,再重新 seed。若你额外修改了列名或类型,恢复完整原文件后可以用 uv run dbt seed --profiles-dir . --full-refresh 重建练习 seed 表;不要在真实环境中把重建当作无成本操作。
本课新增并保留两份 CSV,其他文件沿用第 2 课。现在只是装载并观察输入,还没有建立正式的业务转换。