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

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

1. 前言

在使用SQLAlchemy过程中发现SQLAlchemy的查询集没有类似django-ormvalues()的功能,想通过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()
相关推荐
聆春烟雨簌簌4 分钟前
LangChain4j使用文档
开发语言·python
belong_my_offer18 分钟前
在Pycharm中安装conda的保姆级教学
python
CTA终结者22 分钟前
期货量化合约代码写错:天勤 symbol 格式与 silent 订阅坑
python·区块链
c_lb728822 分钟前
期货程序化撤单改价后仓位乱了:cancel_order 与 TargetPosTask 协作
python
如烟花的信页41 分钟前
加速乐cookie逆向分析
javascript·爬虫·python·js逆向
装不满的克莱因瓶41 分钟前
PyTorch 与它的自动微分工具:Autograd
人工智能·pytorch·python·深度学习·神经网络·机器学习·ai
cd988801 小时前
2026年,电销机器人哪家技术强?
python
weixin199701080161 小时前
[特殊字符] 1688开放平台API Sign签名算法详解(Java / Python / PHP 实现)
java·python·算法
TickDB1 小时前
Python 调用实时行情 API:ticker 返回成功后,如何校验字段再入库或展示
python·websocket·行情数据 api
AC赳赳老秦1 小时前
OpenClaw 助力技术面试:自动生成面试题、模拟面试、整理面试知识点
开发语言·python·面试·职场和发展·自动化·deepseek·openclaw