|
||
---|---|---|
mooc | ||
tests | ||
.env.example | ||
.gitignore | ||
docker-compose.yml | ||
Dockerfile | ||
main.py | ||
README.md | ||
requirements.txt |
ExamService
题库小程序服务端 - FastAPI实现
项目结构
ExamService/
├── alembic/ # 数据库迁移相关
├── mooc/ # 主应用目录
│ ├── api/ # API路由
│ │ └── v1/ # API v1版本
│ ├── core/ # 核心配置
│ ├── crud/ # 数据库操作
│ ├── db/ # 数据库
│ ├── models/ # 数据库模型
│ ├── schemas/ # Pydantic模型
│ └── utils/ # 工具函数
├── tests/ # 测试目录
└── [配置文件]
安装
1. 安装 Miniconda
在 Ubuntu 上安装 Miniconda,执行以下步骤:
# 下载 Miniconda 安装脚本
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
# 给安装脚本添加执行权限
chmod +x Miniconda3-latest-Linux-x86_64.sh
# 运行安装脚本
./Miniconda3-latest-Linux-x86_64.sh
# 按照提示完成安装,选择安装目录并接受许可协议
# 激活 Miniconda
source ~/.bashrc
# 创建名为 'mooc' 的虚拟环境,Python 版本大于等于 3.13
conda create --name mooc python>=3.13
# 激活 'mooc' 环境
conda activate mooc
# 安装依赖
pip install -r requirements.txt
安装mysql开发库
# 更新包列表
apt-get update
# 安装 MySQL 开发包和其他必要的包
apt-get install -y python3-dev default-libmysqlclient-dev build-essential pkg-config
pip install mysqlclient pymysql cryptography
运行
uvicorn main:app --reload
初始化数据库
alembic init alembic
alembic revision --autogenerate -m "Initial migration"
alembic upgrade head
数据库管理
添加新的数据库表
- 创建模型文件:
将同类型的表模型放在同一个文件中。文件命名规则:去除表名的 ims_
前缀,例如:
ims_account_wechats
、ims_account_wxapp
等表 →account.py
ims_uni_account
、ims_uni_settings
等表 →uni_account.py
# filepath: mooc/models/account.py
from sqlalchemy import Column, Integer, String, SmallInteger
from mooc.db.database import Base
class AccountWechats(Base):
"""微信公众号账号表"""
__tablename__ = "ims_account_wechats"
acid = Column(Integer, primary_key=True)
uniacid = Column(Integer, nullable=False)
# ... 其他字段
- 在
mooc/models/__init__.py
中注册表:
# 添加到 expected_tables 集合中
expected_tables = {
# ... 现有表 ...
'ims_account_wechats', # 新添加的表
}
- 导出模型类:
# 在 mooc/models/__init__.py 中添加导出
from mooc.models.account import AccountWechats
- 创建 Schema:
# filepath: mooc/schemas/account.py
from pydantic import BaseModel
class AccountWechatsBase(BaseModel):
uniacid: int
# ... 其他字段
class AccountWechatsCreate(AccountWechatsBase):
pass
class AccountWechatsUpdate(BaseModel):
# 可选字段用于更新
uniacid: Optional[int] = None
class AccountWechatsRead(AccountWechatsBase):
acid: int
class Config:
from_attributes = True
- 创建 CRUD 操作:
# filepath: mooc/crud/crud_account.py
from mooc.crud.crud_base import CRUDBase
class CRUDAccountWechats(CRUDBase[AccountWechats, AccountWechatsCreate, AccountWechatsUpdate]):
def get_by_uniacid(self, db: Session, *, uniacid: int) -> Optional[AccountWechats]:
return self.get_by_field(db, "uniacid", uniacid)
# 创建实例
account_wechats = CRUDAccountWechats(AccountWechats)
- 添加 API 路由:
# filepath: mooc/api/v1/endpoints/account.py
@account_router.post("/wechats", response_model=AccountWechatsRead)
def create_wechat_account(
*,
db: Session = Depends(deps.get_db),
account_in: AccountWechatsCreate,
):
"""创建微信公众号账号"""
return account_wechats.create(db=db, obj_in=account_in)
数据库表自动创建
应用启动时会自动执行以下操作:
- 导入并验证所有模型定义
- 检查数据库中缺失的表
- 自动创建缺失的表
你可以通过查看应用日志了解表创建的详细情况:
python main.py
注意事项
- 模型类名采用帕斯卡命名法(PascalCase),去除
ims_
前缀 - 表名(
__tablename__
)必须与数据库中的实际表名完全一致 - 字段类型要与数据库定义严格匹配
- 确保主键和索引的正确定义
- 添加适当的文档字符串说明表的用途
调试帮助
如果遇到问题,可以:
- 检查日志输出了解具体错误
- 使用
get_all_table_names()
查看已注册的表 - 验证模型定义是否完整
- 确认数据库连接配置是否正确
CRUDBase 使用指南
简介
CRUDBase是一个通用的CRUD基类,提供了基础的增删改查操作。通过继承这个基类,可以快速实现特定模型的CRUD操作。
使用方法
- 创建CRUD类:
from mooc.crud.base import CRUDBase
from mooc.models.your_model import YourModel
from mooc.schemas.your_schema import YourCreateSchema, YourUpdateSchema
class CRUDYourModel(CRUDBase[YourModel, YourCreateSchema, YourUpdateSchema]):
pass # 继承基础功能即可,如需自定义方法可以在这里添加
- 实例化CRUD对象:
crud_your_model = CRUDYourModel(YourModel)
基础操作示例
# 创建记录
new_item = crud_your_model.create(db, obj_in=item_create_schema)
# 获取单条记录
item = crud_your_model.get(db, id=123)
# 获取多条记录
items = crud_your_model.get_multi(db, skip=0, limit=100)
# 更新记录
updated_item = crud_your_model.update(db, db_obj=existing_item, obj_in=item_update_schema)
# 删除记录
crud_your_model.remove(db, id=123)
自定义方法示例
class CRUDYourModel(CRUDBase[YourModel, YourCreateSchema, YourUpdateSchema]):
def get_by_custom_field(self, db: Session, field_value: str) -> Optional[YourModel]:
return db.query(self.model).filter(self.model.custom_field == field_value).first()
注意事项
-
CRUDBase需要三个类型参数:
- ModelType: SQLAlchemy模型类
- CreateSchemaType: Pydantic创建模型
- UpdateSchemaType: Pydantic更新模型
-
所有方法都需要传入数据库会话(db: Session)参数
-
更新操作支持两种方式:
- 字典形式:
update(db, db_obj=item, obj_in={"field": "new_value"})
- Pydantic模型:
update(db, db_obj=item, obj_in=ItemUpdate(field="new_value"))
- 字典形式:
API文档
启动服务后访问: http://localhost:2333/docs
使用 AI 生成模型代码
当你有一个新的数据库表需要添加时,可以使用以下方式让 AI 帮助生成代码:
- 准备 SQL 建表语句,例如:
CREATE TABLE `ims_uni_settings` (
`uniacid` int(10) UNSIGNED NOT NULL,
`passport` varchar(200) NOT NULL,
`oauth` varchar(100) NOT NULL,
-- ... 其他字段
PRIMARY KEY (`uniacid`)
) ENGINE = MyISAM CHARACTER SET = utf8 COLLATE = utf8_general_ci;
- 使用以下提示词模板:
请帮我为这个表生成 FastAPI + SQLAlchemy 的实现,包括:
1. SQLAlchemy 模型(models/xxx.py)
2. Pydantic Schema(schemas/xxx.py)
3. CRUD 操作(crud/crud_xxx.py)
4. API 路由(api/v1/endpoints/xxx.py)
要求:
- 遵循项目的命名规范(去除ims_前缀,使用帕斯卡命名法)
- 确保字段类型映射正确
- 包含必要的文档注释
- 实现基本的 CRUD 操作和常用查询方法
[SQL建表语句]
- 对生成的代码进行以下检查:
- 表名是否与数据库一致
- 字段类型是否正确映射
- 主键和索引是否正确定义
- 是否符合项目的命名规范
- CRUD 方法是否满足业务需求
- 常用的 SQL 类型映射参考:
# MySQL 到 SQLAlchemy 的类型映射
int/bigint -> Integer
varchar/char -> String(length)
text -> Text
datetime -> DateTime
timestamp -> TIMESTAMP
tinyint -> SmallInteger
decimal -> DECIMAL(precision, scale)
- 示例提示词:
我需要为以下数据表生成 FastAPI 实现:
- 表名:ims_uni_settings
- 主键:uniacid
- 特殊需求:
* 需要通过 uniacid 查询的方法
* 需要处理 Text 类型的 payment 字段
* 所有字符串字段都是必填的
[SQL语句]
...
请生成完整的代码实现。
- 代码生成后的集成步骤:
- 将模型类添加到对应的 models 文件
- 在 models/init.py 中注册表名
- 在 api.py 中注册新的路由
- 检查并测试生成的 API 端点
这种方式可以:
- 快速生成符合项目规范的代码
- 确保类型映射的准确性
- 保持代码结构的一致性
- 减少手动编码的错误