Pydantic增强SQLALchemy序列化(FastAPI直接输出SQLALchemy查询集)

Pydantic增强SQLALchemy序列化(FastAPI直接输出SQLALchemy查询集)

1. 前言

在使用SQLAlchemy过程中发现SQLAlchemy的查询集没有类似django-orm中values()的功能,想通过Pydantic添加个实现类似的功能 还有就是pandas明明支持SQLAlchemy模块,但读取数据的时候还只能通过引擎+SQL语句的模式,实在不够优雅,想着查询集先直接出个字典类数据pandas直接解析

2. 定义SQLALchemy

python 复制代码
from sqlalchemy.orm import declarative_base

# 创建基础模型类
Base = declarative_base()

# 定义一个简单的模型
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    age = Column(Integer)

3. 定义pydantic

python 复制代码
class UserModel(BaseModel):
    id: int = Field(..., description="用户ID")
    name: str = Field(..., description="用户名")
    age: int = Field(..., description="用户年龄")

    model_config = {
        'from_attributes': True
    }

class UserListModel(RootModel):
    root: list[UserModel]
    model_config = {
        'from_attributes': True
    }

4. pydantic序列化SQLALchemy查询集

已经提前添加测试数据

python 复制代码
# 创建数据库引擎
engine = create_engine('sqlite:///test.db')
# 创建表
Base.metadata.create_all(engine)
# 创建会话
Session = sessionmaker(bind=engine)
session = Session()
users = session.query(User).all()
# 将查询结果转换为Pydantic模型
user_list = UserListModel.model_validate(users)
# 转成字典
user_list.model_dump()
# 转成json
user_list.model_dump_json()
# 一步到位的写法
UserListModel.model_validate(users).model_dump_json()

5. 与FatAPI配合

python 复制代码
app = FastAPI()
@app.get("/",response_model=UserListModel)
def read_root():
    with session as db:
        users = db.query(User).all()
        return users

6. 总结

研究完发现这个方法感觉有点多此一举,除了可以用于FastAPI直接输出SQLAlchemy查询集内容外,好像没啥优点了,能更优雅一点?还因为需要定义定义Pydantic反而更复杂一些,建议可以在有Pydantic+Pydantic项目中使用,尤其是FastAPI项目

7. 附录:传统使用方式

常规方式是在模型当中添加一个自定义to_dict()的方法,然后通过列表迭代的方式重新组成查询集字典

python 复制代码
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# 创建基础模型类
Base = declarative_base()

# 定义一个简单的模型
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    age = Column(Integer)

    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'age': self.age
        }

# 创建数据库引擎
engine = create_engine('sqlite:///test.db')
# 创建表
Base.metadata.create_all(engine)
# 创建会话
Session = sessionmaker(bind=engine)
session = Session()
# 添加一些示例数据
new_user = User(name='John', age=30)
session.add(new_user)
session.commit()
# 查询数据并转换为字典
users = session.query(User).all()
user_dicts = [user.to_dict() for user in users]
# 打印结果
print(user_dicts)
# 关闭会话
session.close()
相关推荐
专注仿真5 小时前
梯度提升类(XFBoost)算法详解与代码实例
开发语言·人工智能·python·算法·大模型训练·控制算法
外收内放5 小时前
Python基础语法练习题(75)
开发语言·python·学习
黑十6 小时前
PyTorch 报 “no CUDA GPUs are available“ 怎么办?3 步排查
服务器·网络·人工智能·pytorch·python
threelab7 小时前
开源图片去水印代码
python
taller_20008 小时前
【012】数据类型入门: Excel 数据到 Python 值的转换
python·excel·pie·py
淡漠的蓝精灵8 小时前
web.py:一个简单到极致的 Python Web 框架
开发语言·前端·python·其他
起个名字费劲死了9 小时前
Halcon学习一:骰子识别
前端·python·学习
eric-sjq9 小时前
小思框架 · 30M 级长上下文新架构对比技术报告
人工智能·python·深度学习·语言模型
reasonsummer11 小时前
【办公类-04-05】20261030整理手机照片(华为手机助手导出照片到日期文件夹+批量添加四级文件夹+手动转移照片更名+更改三级文件夹合并汉字名称)
python·智能手机
BD_Marathon12 小时前
【Python】初识迭代器
python