包含 Docker Compose 快速启动、独立安装、Alembic 迁移、多仓库 schema 同步工作流。 明确禁止打包本地数据库镜像(PII 泄露风险 + schema 分叉),所有环境通过迁移文件同步表结构。 Co-Authored-By: Claude <noreply@anthropic.com>
12 KiB
PostgreSQL 数据库搭建指南
本项目运行时必须连接 PostgreSQL 16+(含 pgvector 扩展),SQLite 已不支持。
方案一:Docker Compose(推荐,本地开发)
适合本地开发与测试,一条命令启动 PostgreSQL + pgvector。
1. 创建 docker-compose.yml
在项目根目录或任意位置新建:
version: '3.8'
services:
postgres:
image: pgvector/pgvector:pg16
container_name: resume-agent-db
environment:
POSTGRES_USER: resume_agent
POSTGRES_PASSWORD: change-me-in-production
POSTGRES_DB: resume_agent
ports:
- "5435:5432"
volumes:
- resume_agent_data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
resume_agent_data:
2. 启动
docker-compose up -d
3. 配置 backend/.env
DATABASE_URL=postgresql+psycopg://resume_agent:change-me-in-production@127.0.0.1:5435/resume_agent
RESUME_AGENT_TEST_DATABASE_URL=postgresql+psycopg://resume_agent:change-me-in-production@127.0.0.1:5435/resume_agent_test
4. 初始化数据库
cd backend
alembic upgrade head
停止与清理:
docker-compose down # 停止(保留数据)
docker-compose down -v # 停止并删除数据卷(重置数据库)
方案二:生产环境 PostgreSQL
适合公司已有 PostgreSQL 集群或需要独立部署的场景。
1. 安装 PostgreSQL 16+
Ubuntu/Debian:
sudo apt install postgresql-16 postgresql-contrib-16
CentOS/RHEL:
sudo dnf install postgresql16-server postgresql16-contrib
sudo postgresql-16-setup initdb
sudo systemctl enable --now postgresql-16
macOS(Homebrew):
brew install postgresql@16
brew services start postgresql@16
Windows:下载官方安装包 https://www.postgresql.org/download/windows/
2. 安装 pgvector 扩展
pgvector 用于向量存储(未来扩展知识库功能时需要,当前轻度优化不依赖)。
Ubuntu/Debian:
sudo apt install postgresql-16-pgvector
从源码安装(如包管理器无 pgvector):
git clone https://github.com/pgvector/pgvector.git
cd pgvector
make PG_CONFIG=/usr/pgsql-16/bin/pg_config # 路径按实际调整
sudo make install PG_CONFIG=/usr/pgsql-16/bin/pg_config
3. 创建用户与数据库
以 postgres 管理员身份执行:
CREATE USER resume_agent WITH PASSWORD 'your-strong-password';
CREATE DATABASE resume_agent OWNER resume_agent;
CREATE DATABASE resume_agent_test OWNER resume_agent;
-- 启用 pgvector 扩展(当前可选,未来知识库功能需要)
\c resume_agent
CREATE EXTENSION IF NOT EXISTS vector;
\c resume_agent_test
CREATE EXTENSION IF NOT EXISTS vector;
-- 授权(如果数据库归属已设为 resume_agent 则自动有权限,此行可跳过)
GRANT ALL PRIVILEGES ON DATABASE resume_agent TO resume_agent;
GRANT ALL PRIVILEGES ON DATABASE resume_agent_test TO resume_agent;
4. 配置 backend/.env
将 host、port、密码替换为实际值:
DATABASE_URL=postgresql+psycopg://resume_agent:your-strong-password@your-db-host:5432/resume_agent
RESUME_AGENT_TEST_DATABASE_URL=postgresql+psycopg://resume_agent:your-strong-password@your-db-host:5432/resume_agent_test
注意:生产环境必须修改默认密码 change-me-in-production。
5. 初始化数据库
cd backend
alembic upgrade head
验证安装
检查连接
cd backend
python -c "from app.postgres_database import PostgresDatabase; db = PostgresDatabase('your-DATABASE_URL-here', 'resume_agent'); db.initialize(); print('✓ 连接成功')"
运行测试(需要测试库)
cd backend
pytest tests/test_postgres_environment.py -v
常见问题
Q1: ModuleNotFoundError: No module named 'psycopg'
安装 Python 驱动:
pip install psycopg[binary]
Q2: FATAL: password authentication failed
- 检查
.env中的密码是否正确 - PostgreSQL 默认可能只允许本地 Unix socket 连接,需修改
pg_hba.conf:修改后重启 PostgreSQL:# 允许密码认证(开发环境) host all all 127.0.0.1/32 md5sudo systemctl restart postgresql-16
Q3: FATAL: database "resume_agent" does not exist
执行方案二第 3 步创建数据库。
Q4: could not open extension control file ".../vector.control"
pgvector 未安装或路径不对,执行方案二第 2 步。当前轻度优化功能可暂不安装(但测试套件会跳过 pgvector 相关测试)。
从 SQLite 迁移到 PostgreSQL
如果你有旧的 SQLite 数据库(backend/data/resume_agent.db),可一键迁移:
cd backend
# 确保 PostgreSQL 已启动且 alembic upgrade head 已执行
python scripts/migrate_sqlite_to_postgres.py \
--sqlite-path data/resume_agent.db \
--postgres-url "postgresql+psycopg://resume_agent:password@127.0.0.1:5435/resume_agent"
迁移完成后 SQLite 文件可归档备份(不要删除,以防回滚)。
多环境 Schema 隔离(可选)
如果多个开发者或环境共用一个 PostgreSQL 实例,可用不同 schema 隔离:
# 开发者 A
export RESUME_AGENT_DATABASE_SCHEMA=dev_alice
# 开发者 B
export RESUME_AGENT_DATABASE_SCHEMA=dev_bob
# 测试 CI
export RESUME_AGENT_DATABASE_SCHEMA=ci_test
每个 schema 自动创建独立表,互不影响。默认 schema 是 resume_agent。
⚠️ 为什么不要打包现有数据库镜像
如果你已在本地运行过项目并考虑"把我的数据库导出给其他人用",请不要这样做:
| 问题 | 后果 |
|---|---|
| 本地库含测试 PII | 测试用的真实简历、手机号会随镜像泄露到其他环境 |
| schema 版本分裂 | 如果本地库含未发布的表结构(如深度优化功能的实验性迁移),其他人拿到的库与代码不匹配 |
| 无法追踪变更 | 镜像是"某一时刻的快照",后续表结构变更无法增量同步,只能重新导出(覆盖生产数据)或手写 SQL 补丁 |
| 违反 Alembic 设计 | Alembic 迁移链才是 schema 的唯一事实来源;绕过它会导致 alembic current 显示错误版本,后续 upgrade 失败 |
正确做法:每个环境独立执行 alembic upgrade head(从零建表),通过迁移文件而非数据库快照同步 schema。
多仓库协作:如何同步 Schema 变更(Alembic 迁移)
适用场景:原始开发仓库(含深度优化等未发布功能)与交付仓库(resume-agent-offerpai)分离,需定期同步表结构。
原则
- Alembic 迁移文件是 schema 的唯一事实来源,不传数据库镜像
- 每个环境通过
alembic upgrade head应用迁移,保证 schema 一致 - 新功能的表结构变更先在开发仓库测试,稳定后再合并进交付仓库
工作流
1. 开发仓库添加新功能(如深度优化)
当你在原始仓库开发深度优化功能并需要新增表时:
# 在开发仓库 backend/
alembic revision -m "add deep optimization knowledge tables"
Alembic 会生成新迁移文件,例如 backend/alembic/versions/20260806_06_add_deep_knowledge.py。
编辑该文件实现表结构变更:
def upgrade() -> None:
op.create_table(
'knowledge_entries',
sa.Column('id', sa.Integer(), primary_key=True),
sa.Column('content', sa.Text(), nullable=False),
# ... 其他列
)
def downgrade() -> None:
op.drop_table('knowledge_entries')
在本地测试:
alembic upgrade head # 应用迁移
alembic downgrade -1 # 回滚测试
alembic upgrade head # 重新应用
pytest tests/test_deep_optimization.py # 功能测试
2. 决定是否合并进交付仓库
开发完成后,根据发布计划决定:
情况 A:深度优化暂不发布
→ 迁移文件留在开发仓库,交付仓库不同步(两个仓库的 schema 暂时分叉)
情况 B:深度优化已稳定,准备发布
→ 将新迁移文件复制进交付仓库:
# 复制迁移文件
cp resume-agent/backend/alembic/versions/20260806_06_*.py \
resume-agent-offerpai/backend/alembic/versions/
# 同时复制相关代码模块
cp -r resume-agent/backend/app/deep_optimization \
resume-agent-offerpai/backend/app/
3. 交付仓库用户升级数据库
其他开发者或生产环境拉取最新代码后:
cd backend
alembic upgrade head
Alembic 会自动检测本地数据库版本,只应用新增的迁移(如 06_add_deep_knowledge.py),已有的表结构不受影响。
验证迁移成功:
alembic current
# 输出:06 (head), add deep optimization knowledge tables
4. 回滚(如果新功能有问题)
alembic downgrade -1 # 回退一个版本
# 或指定目标版本
alembic downgrade 05
注意事项
- 迁移文件命名保持顺序:Alembic 按文件名前缀排序(
20260806_06_),不要手动改编号 - 不要修改已发布的迁移:已在生产环境执行的迁移文件禁止编辑;如需修正,写新的迁移
- 复制迁移时检查依赖:如果新迁移引用了其他未发布的表,需一并复制依赖的迁移
- 测试先行:新迁移在开发环境验证通过后再合并;生产环境升级前先在预发环境测试
查看迁移历史
alembic history --verbose
# 显示完整迁移链与当前版本
如果两个仓库的迁移链已分叉
如果长期未同步导致迁移编号冲突(例如两边都有 06_ 开头的迁移但内容不同):
# 在交付仓库重新编号新迁移
cd resume-agent-offerpai/backend
alembic revision -m "sync: merge deep optimization from main repo"
# 手动编辑生成的文件,将开发仓库的迁移内容复制进来
最佳实践:定期(如每次发版)同步迁移文件,避免分叉。
示例:完整的多仓库协作流程
场景:你在开发仓库完成了深度优化功能,需要同步到交付仓库供公司团队使用。
Step 1:开发仓库提交迁移
cd resume-agent/backend
alembic revision -m "add deep optimization tables"
# 编辑生成的迁移文件,实现 upgrade/downgrade
alembic upgrade head
pytest # 验证功能
git add alembic/versions/20260806_06_*.py app/deep_optimization/
git commit -m "feat: add deep optimization module with knowledge tables"
Step 2:同步到交付仓库
cd ../resume-agent-offerpai
cp ../resume-agent/backend/alembic/versions/20260806_06_*.py \
backend/alembic/versions/
cp -r ../resume-agent/backend/app/deep_optimization \
backend/app/
git add backend/alembic/versions/ backend/app/deep_optimization/
git commit -m "feat: sync deep optimization from main repo"
git push origin master
Step 3:公司团队升级
# 其他开发者拉取最新代码
git pull origin master
cd backend
alembic upgrade head
# 输出:
# INFO [alembic.runtime.migration] Running upgrade 05 -> 06, add deep optimization tables
pytest # 验证本地环境
Step 4:生产环境升级(零停机)
# 生产服务器
cd /opt/resume-agent/backend
git pull
alembic upgrade head # Alembic 自动只应用新迁移,已有数据不受影响
sudo systemctl restart resume-agent
总结
| 场景 | 推荐方案 |
|---|---|
| 首次部署 | 方案一(Docker Compose)或方案二(独立 PG),然后 alembic upgrade head |
| 多人协作 | 每人独立建库 + 共享迁移文件(通过 Git),不传数据库镜像 |
| Schema 升级 | 开发仓库写迁移 → 测试 → 复制到交付仓库 → 其他人 alembic upgrade |
| 数据迁移 | 用迁移文件的 op.execute("INSERT ...") 或独立脚本(如 scripts/seed_demo_data.py) |
| 回滚 | alembic downgrade <target_revision> |
禁止操作:pg_dump 整个库然后 psql < dump.sql 覆盖他人数据库 —— 会破坏 Alembic 版本追踪。