# 第 2 章 配套代码

> 演示「图书管理系统」（`ch2_books / ch2_authors / ch2_categories`）下 psql + psycopg 的常见编程姿势。

## 准备工作

1. 跑初始化脚本建表 + 灌测试数据：
   ```bash
   psql -h 127.0.0.1 -U postgres -d learn_pg -f ../init.sql
   ```
2. 安装依赖：
   ```bash
   pip install "psycopg[binary]>=3.1"
   ```
3. （可选）通过环境变量覆盖默认连接信息：
   ```bash
   export PG_DSN="host=127.0.0.1 port=5432 dbname=learn_pg user=postgres"
   ```

## 脚本一览

| 脚本 | 一句话说明 | 关键 PG 特性 |
|------|------------|--------------|
| `basic_query.py` | 用 psycopg v3 打通连接、查询、事务、批量写入、流式读 | 参数化查询、`INSERT ... RETURNING`、`executemany`、`COPY FROM STDIN`、`sql.Identifier`、服务端游标 |

> 后续随着章节推进，本目录会陆续新增 `transaction_savepoint.py` / `copy_csv_loader.py` 等脚本，统一遵循「先建表 → 再 `python xxx.py`」的运行约定。

## 预期输出

`basic_query.py` 跑完会看到 7 段 demo 输出，关键片段大致是：

```
──────────────────────────────────────────────────────────────────────
  Demo 1 · 基础查询 + 参数化查询
──────────────────────────────────────────────────────────────────────
ch2_books 总条数 : 14
分类 = 科幻, 库存 >= 1 的 Top5：
  #3    三体 III：死神永生              author=刘慈欣      ¥42.00  stock=25
  ...

──────────────────────────────────────────────────────────────────────
  Demo 2 · INSERT ... RETURNING 一次拿到主键 + 时间戳
──────────────────────────────────────────────────────────────────────
  新书已插入：id=15, created_at=2026-04-17 10:00:00+08
...
✅ All demos done.
```

## 常见报错

- `connection refused` → PG 没起 / 端口不对 / 监听 `localhost` 时用了 `127.0.0.1` 之外的 host
- `relation "ch2_books" does not exist` → 没跑 `../init.sql`
- `password authentication failed` → 修改 `~/.pgpass` 或环境变量 `PGPASSWORD`
- `permission denied for sequence ch2_books_id_seq` → 用 `IDENTITY` 而非 `SERIAL` 时不会出现；如果出现，说明老库残留了 `SERIAL` 的序列对象，重新跑 `init.sql` 即可
