内部培训
02 第2周D11 PostgresSQL

D11 作业:建表查询 + 给 D10 的 API 接上数据库

D11 作业:建表查询 + 给 D10 的 API 接上数据库

目标

  • 验证:会建表/查询/事务、理解金额用 NUMERIC,能把 FastAPI 接上 Postgres。

场景

  • 本地开发机;本地 Postgres(Docker:docker run -d --name pg16 -e POSTGRES_PASSWORD=z1a2q3W4 -p 5432:5432 postgres:16)。

任务

任务 1:建表 + 基础查询

-- 连上后执行
CREATE DATABASE labdb;   -- 或直接连默认库
  • 建两张表(符合课程口径):
CREATE TABLE users (
  id      BIGSERIAL PRIMARY KEY,
  name    TEXT NOT NULL,
  balance NUMERIC(20,8) NOT NULL DEFAULT 0
);
CREATE TABLE bills (
  id         BIGSERIAL PRIMARY KEY,
  user_id    BIGINT NOT NULL REFERENCES users(id),
  amount     NUMERIC(20,8) NOT NULL,
  type       TEXT NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
  • 插入 3 个用户、若干流水;写出 3 条查询:余额 >0 的用户、按 type 分组统计、某用户的总消费(JOIN)。

任务 2:验证事务(重点)

BEGIN;
UPDATE users SET balance = balance - 10 WHERE id = 1;
INSERT INTO bills (user_id, amount, type) VALUES (1, 10, 'chat');
COMMIT;   -- 观察余额与流水一致

-- 再试一次中途 ROLLBACK,验证"要么全成要么全不成"
BEGIN;
UPDATE users SET balance = balance - 10 WHERE id = 1;
ROLLBACK;  -- 观察余额没变
  • 用文字回答:为什么扣费必须用事务?如果"扣了余额但流水没记"会怎样?

任务 3:给 D10 的 API 接库(选做加分)

  • 用 asyncpg 把 D10 的 users CRUD 从内存 dict 换成真库。
  • 至少实现 GET /users/{uid} 读库、POST /users 写库,其余可留 TODO。

验收标准(讲师核验用)

  • 任务 1:两张表结构正确(含外键),3 条查询输出正确
  • 任务 2:事务两段演示结果正确,能口头解释原子性
  • 任务 3(加分):CRUD 已从 dict 换成真库并能跑通

提交方式

  • SQL 脚本与回答放 docs/training/学员/<姓名>/D11/,按 D6 流程提交 PR,中文提交信息,如:D11 作业:SQL与事务(姓名)

参考

  • 课程.md 第 2、4、5、6 节
  • 学习网站.md → D11 分组

On this page