# 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` ```python # ❌ 错误(中文引号) 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()` 调用: ```python # ❌ 错误(多条语句) 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. 迁移执行成功 ```bash docker exec jointo-server-app alembic upgrade head # ✅ 成功创建 5 个表 # ✅ 成功创建 27 个索引 # ✅ 成功添加 5 个表注释 # ✅ 成功添加 55 个字段注释 # ✅ 成功创建 4 个触发器 ``` ### 2. 表结构验证 ```sql -- 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` ## 下一步 1. ✅ 数据库迁移完成 2. ⏭️ 注册 API 路由到 FastAPI 3. ⏭️ 配置 Celery Beat 定时任务 4. ⏭️ 编写单元测试 5. ⏭️ API 功能测试