# SQLAlchemy 2.0 规范合规性修复 **日期**: 2026-02-09 **类型**: 技术债务修复 **影响范围**: Repository 层 ## 问题描述 项目中多个 Repository 文件存在不符合 SQLAlchemy 2.0 规范的代码模式: 1. **重复执行查询**:同一条 SQL 语句被执行两次 2. **错误的结果提取**:直接使用 `result.all()` 而不是 `result.scalars().all()` 这些问题会导致: - 性能问题(重复执行查询) - 返回错误的数据类型(Row 对象而不是模型对象) - 不符合 SQLAlchemy 2.0 最佳实践 ## 修复内容 ### 修复的文件(10 个) 1. `server/app/repositories/folder_export_repository.py` 2. `server/app/repositories/folder_share_repository.py` 3. `server/app/repositories/storyboard_resource_repository.py` 4. `server/app/repositories/user_repository.py` 5. `server/app/repositories/screenplay_repository.py` 6. `server/app/repositories/project_repository.py` 7. `server/app/repositories/project_resource_repository.py` 8. `server/app/repositories/project_resource_share_repository.py` 9. `server/app/repositories/project_element_tag_repository.py` 10. `server/app/repositories/base_repository.py` ### 修复模式 #### 问题 1:重复执行查询 ```python # ❌ 修复前 result = await self.session.execute(statement) result = await self.session.execute(statement) # 重复执行 return list(result.all()) ``` ```python # ✅ 修复后 result = await self.session.execute(statement) return list(result.scalars().all()) ``` #### 问题 2:错误的结果提取 ```python # ❌ 修复前 result = await self.session.execute(stmt) return list(result.all()) # 返回 Row 对象 ``` ```python # ✅ 修复后 result = await self.session.execute(stmt) return list(result.scalars().all()) # 返回模型对象 ``` #### 问题 3:批量查询结果提取 ```python # ❌ 修复前 result = await self.session.execute(stmt) result = await self.session.execute(stmt) images = result.all() ``` ```python # ✅ 修复后 result = await self.session.execute(stmt) images = result.scalars().all() ``` ## 修复统计 - **总计修复点**:约 30 处 - **涉及方法**: - `get_user_jobs()` - folder_export_repository - `get_expired_jobs()` - folder_export_repository - `get_folder_shares()` - folder_share_repository - `get_user_shared_folders()` - folder_share_repository - `get_images_by_storyboard()` - storyboard_resource_repository - `get_videos_by_storyboard()` - storyboard_resource_repository - `get_dialogues_by_storyboard()` - storyboard_resource_repository - `get_voiceovers_by_dialogue()` - storyboard_resource_repository - `deactivate_all_images()` - storyboard_resource_repository - `deactivate_all_videos()` - storyboard_resource_repository - `deactivate_all_voiceovers()` - storyboard_resource_repository - `get_sessions_by_user_id()` - user_repository - `delete_sessions_by_user_id()` - user_repository - `get_trashed_projects()` - project_repository - `get_by_user()` - project_repository - `get_by_folder()` - project_repository - `get_members()` - project_repository - `get_shares()` - project_repository - `get_subprojects()` - project_repository - `get_versions()` - screenplay_repository - `count_by_project_ids()` - screenplay_repository - `count_by_parent_project_ids()` - screenplay_repository - `get_by_project()` - project_resource_repository - `get_by_element_tag_id()` - project_resource_repository - `get_by_element()` - project_resource_repository - `get_by_target_project()` - project_resource_share_repository - `get_by_element()` - project_element_tag_repository - `get_by_project()` - project_element_tag_repository - `get_all()` - base_repository ## 验证结果 ✅ 所有修复的文件通过 `getDiagnostics` 检查,无语法错误 ✅ 使用 `grepSearch` 验证,确认无重复执行模式残留 ✅ 代码符合 SQLAlchemy 2.0 规范 ## SQLAlchemy 2.0 最佳实践 ### 查询单个模型对象 ```python # ✅ 正确 result = await session.execute(select(Model).where(...)) obj = result.scalar_one_or_none() # 或 scalars().first() ``` ### 查询多个模型对象 ```python # ✅ 正确 result = await session.execute(select(Model).where(...)) objects = result.scalars().all() ``` ### 查询聚合结果(count, sum 等) ```python # ✅ 正确 result = await session.execute(select(func.count(Model.id))) count = result.scalar_one() ``` ### 查询多列或 JOIN 结果 ```python # ✅ 正确(返回元组) result = await session.execute( select(Model1.id, Model2.name).join(...) ) rows = result.all() # 返回 [(id1, name1), (id2, name2), ...] ``` ## 影响评估 - **性能提升**:消除了约 30 处重复查询,减少数据库负载 - **数据正确性**:确保返回正确的模型对象类型 - **代码质量**:符合 SQLAlchemy 2.0 官方规范 - **向后兼容**:修复不影响现有功能,仅改进实现方式 ## 后续建议 1. **代码审查**:在 PR 审查时检查 SQLAlchemy 查询模式 2. **Linter 规则**:考虑添加自定义 Linter 规则检测重复执行 3. **文档更新**:在技术栈文档中明确 SQLAlchemy 2.0 规范 4. **培训**:团队成员学习 SQLAlchemy 2.0 最佳实践 ## 参考资料 - [SQLAlchemy 2.0 Migration Guide](https://docs.sqlalchemy.org/en/20/changelog/migration_20.html) - [SQLAlchemy 2.0 Tutorial](https://docs.sqlalchemy.org/en/20/tutorial/) - Jointo Tech Stack Skill - `backend.md`