从 Cloudflare D1 迁移到 PostgreSQL

October, 7th 2025 3 min read

更新时间:2025-09-07

本文档给出从 Cloudflare D1 (SQLite) 迁移数据到 PostgreSQL 的示例流程与脚本。


1. 总体流程

  1. 导出 D1 数据:从 Cloudflare D1 导出 CSV/NDJSON 文件。
  2. 建 PG Schema:使用兼容的 Schema(UUID/ULID 主键、BIGINT 时间戳、TEXT JSON 等)。
  3. 导入 PG:使用 psql \copy 或脚本批量导入。
  4. 校验:行数校验、主键唯一性、抽样哈希校验。
  5. 切换应用:更改 Drizzle ORM 数据源 → Postgres。

2. 导出 D1 数据

Cloudflare Wrangler 提供导出工具:

bash
12345
      # 导出整个数据库为 SQLite 文件
wrangler d1 export guess_db --local --output=backup.sqlite

# 或者导出为 SQL dump
wrangler d1 export guess_db --output=backup.sql
    

如果需要 CSV:

bash
1234
      sqlite3 backup.sqlite \
  -header -csv "SELECT * FROM users;" > users.csv
sqlite3 backup.sqlite \
  -header -csv "SELECT * FROM sessions;" > sessions.csv
    

3. PostgreSQL 建表

示例(users):

sql
12345678
      CREATE TABLE users (
  id TEXT PRIMARY KEY,
  username TEXT NOT NULL UNIQUE,
  password_hash TEXT NOT NULL,
  is_admin INTEGER NOT NULL DEFAULT 0,
  created_at BIGINT NOT NULL,
  last_active_at BIGINT
);
    

完整表结构见 db-compatibility.md


4. 导入 PG

使用 psql \copy

bash
12345
      \copy users(id,username,password_hash,is_admin,created_at,last_active_at) \
FROM 'users.csv' DELIMITER ',' CSV HEADER;

\copy sessions(id,status,host_username,started_at,ended_at) \
FROM 'sessions.csv' DELIMITER ',' CSV HEADER;
    

或用 pgloader(支持 SQLite → PG 直接迁移):

lisp
12345
      LOAD DATABASE
     FROM sqlite:///backup.sqlite
     INTO postgresql://user:pass@localhost:5432/mydb

 WITH include drop, create tables, create indexes, reset sequences;
    

5. 校验

  • 行数:确认表记录数一致。
  • 约束:检查主键、唯一索引。
  • 抽样:对比用户哈希或时间戳,确认一致。

6. 应用切换

Drizzle ORM 切换:

ts
12345678910
      // D1
import { drizzle as drizzleD1 } from "drizzle-orm/d1";
const db = drizzleD1(env.DB);

// PostgreSQL
import { drizzle as drizzlePg } from "drizzle-orm/node-postgres";
import { Client } from "pg";
const pg = new Client({ connectionString: process.env.DATABASE_URL });
await pg.connect();
const db = drizzlePg(pg);
    

业务层(Repository/Service)无需修改。


7. 建议

  • 小规模数据:CSV 导出/导入足够。
  • 大规模数据:用 pgloader,能自动建表并迁移索引。
  • 迁移前建议在测试库跑一遍,确认 Schema & 数据一致。

8. 总结

  • 导出 → 导入 → 校验 → 切换。
  • 推荐 pgloader 做全量迁移。
  • 应用层只需改 Drizzle 数据源,业务逻辑不变。