You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4.3 KiB
4.3 KiB
Credit Service 部署修复
日期: 2026-01-28
类型: Bugfix
影响范围: Credit Service 数据库迁移
问题描述
在执行 Credit Service 数据库迁移时遇到两个问题:
1. Python 语法错误
- 位置:
server/app/models/credit/package.py第 38 行 - 错误: 字段描述中使用了中文引号
"热销"、"推荐"导致 Python 解析失败 - 错误信息:
SyntaxError: invalid character '"' (U+201C)
2. Alembic 迁移脚本错误
- 位置:
server/alembic/versions/20260128_2200_create_credit_service_tables.py - 错误: asyncpg 不支持在单个
op.execute()中执行多条 SQL 语句 - 错误信息:
asyncpg.exceptions.PostgresSyntaxError: cannot insert multiple commands into a prepared statement
修复方案
1. 修复 Python 语法错误
修改文件: server/app/models/credit/package.py
# ❌ 错误(中文引号)
badge_text: Optional[str] = Field(default=None, description="徽章文本(如"热销"、"推荐"等)")
# ✅ 正确(转义引号)
badge_text: Optional[str] = Field(default=None, description="徽章文本(如\"热销\"、\"推荐\"等)")
2. 修复 Alembic 迁移脚本
修改文件: server/alembic/versions/20260128_2200_create_credit_service_tables.py
将所有多条 SQL 语句拆分为单独的 op.execute() 调用:
# ❌ 错误(多条语句)
op.execute("""
CREATE INDEX idx1 ON table1(col1);
CREATE INDEX idx2 ON table2(col2);
""")
# ✅ 正确(单条语句)
op.execute("CREATE INDEX idx1 ON table1(col1)")
op.execute("CREATE INDEX idx2 ON table2(col2)")
修改内容:
- 索引创建:27 条索引语句拆分为 27 个独立调用
- 表注释:5 条注释语句拆分为 5 个独立调用
- 字段注释:55 条注释语句保持循环执行(已是单条)
- 触发器创建:4 条触发器语句拆分为 4 个独立调用
- downgrade 函数:5 条 DROP 语句拆分为 5 个独立调用
验证结果
1. 迁移执行成功
docker exec jointo-server-app alembic upgrade head
# ✅ 成功创建 5 个表
# ✅ 成功创建 27 个索引
# ✅ 成功添加 5 个表注释
# ✅ 成功添加 55 个字段注释
# ✅ 成功创建 4 个触发器
2. 表结构验证
-- credit_transactions 表
\d+ credit_transactions
-- ✅ 11 个字段,所有字段都有中文注释
-- ✅ 8 个索引(包括主键)
-- ✅ 1 个 updated_at 触发器
-- credit_consumption_logs 表
\d+ credit_consumption_logs
-- ✅ 16 个字段,所有字段都有中文注释
-- ✅ 11 个索引(包括主键)
-- ✅ 1 个 updated_at 触发器
-- credit_packages 表
\d+ credit_packages
-- ✅ 12 个字段,所有字段都有中文注释
-- ✅ 2 个索引(包括主键)
-- ✅ 1 个 updated_at 触发器
-- credit_pricing 表
\d+ credit_pricing
-- ✅ 7 个字段,所有字段都有中文注释
-- ✅ 2 个索引(包括主键)
-- ✅ 1 个 updated_at 触发器
-- credit_gifts 表
\d+ credit_gifts
-- ✅ 9 个字段,所有字段都有中文注释
-- ✅ 5 个索引(包括主键)
-- ✅ 无触发器(无 updated_at 字段)
经验总结
1. Python 字符串规范
- 禁止使用中文引号:
""、''会导致语法错误 - 使用英文引号:
""、'' - 引号嵌套:使用转义
\"或单双引号混用
2. Alembic + asyncpg 规范
- 单条语句原则:每个
op.execute()只执行一条 SQL 语句 - 避免批量执行:不要使用
;分隔多条语句 - 循环执行:对于大量相似语句,使用 Python 循环
3. 数据库注释规范
- 表注释:
COMMENT ON TABLE table_name IS '描述' - 字段注释:
COMMENT ON COLUMN table.column IS '描述' - 时区标注:时间字段注释需标注
(UTC) - 关联标注:关联字段注释需标注
- 应用层验证
相关文档
- 设计文档:
docs/requirements/backend/04-services/user/credit-service.md - 实施文档:
docs/server/changelogs/2026-01-28-credit-service-implementation.md - 技术栈规范:
.claude/skills/jointo-tech-stack/references/database.md
下一步
- ✅ 数据库迁移完成
- ⏭️ 注册 API 路由到 FastAPI
- ⏭️ 配置 Celery Beat 定时任务
- ⏭️ 编写单元测试
- ⏭️ API 功能测试