FastAPI + SQLAlchemy 数据库对象转字典

复制代码
def object_as_dict_list(db_list):
    return [{**object_as_dict(item)} for item in db_list]

def object_as_dict(obj):
    return {column.name: getattr(obj, column.name) for column in obj.__table__.columns}

1. object_as_dict(obj) 函数(基础转换器)

复制代码
def object_as_dict(obj):
    return {column.name: getattr(obj, column.name) for column in obj.__table__.columns}
复制代码
工作原理:
  • obj.__table__.columns:获取 SQLAlchemy 模型的所有列定义

  • for column in obj.__table__.columns:遍历每一列

  • column.name:获取列的名称(字段名)

  • getattr(obj, column.name):获取对象在该字段上的值

  • {column.name: getattr(obj, column.name) for ...}:字典推导式,创建字段名到值的映射

示例:

假设有一个 User 模型:

复制代码
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    email = Column(String)

调用 object_as_dict(user_obj) 会返回:

{'id': 1, 'name': 'Alice', 'email': 'alice@example.com'}

2. object_as_dict_list(db_list) 函数(批量转换器)

复制代码
def object_as_dict_list(db_list):
    return [{**object_as_dict(item)} for item in db_list]

工作原理:

  • for item in db_list:遍历数据库对象列表中的每个对象

  • object_as_dict(item):将每个对象转换为字典

  • {**object_as_dict(item)}:使用字典解包创建新字典

  • [...]:列表推导式,将所有结果收集到新列表中

示例:

输入:[<User id=1>, <User id=2>]

输出:

复制代码
[
    {'id': 1, 'name': 'Alice', 'email': 'alice@example.com'},
    {'id': 2, 'name': 'Bob', 'email': 'bob@example.com'}
]

为什么需要 {**dict} 解包操作?

安全性考虑:创建副本避免意外修改

复制代码
# 没有解包的情况(潜在风险)
def risky_object_as_dict_list(db_list):
    return [object_as_dict(item) for item in db_list]

result = risky_object_as_dict_list(users)
result[0]['name'] = 'Modified'  # 这可能影响原始对象!

# 使用解包的情况(安全)
def safe_object_as_dict_list(db_list):
    return [{**object_as_dict(item)} for item in db_list]

result = safe_object_as_dict_list(users)  
result[0]['name'] = 'Modified'  # 安全,不影响原始对象
复制代码

在 FastAPI 路由中使用:

复制代码
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session

router = APIRouter()

@router.get("/users")
async def get_users(db: Session = Depends(get_db)):
    # 查询数据库获取对象列表
    users = db.query(User).all()
    
    # 转换为字典列表(适合JSON响应)
    return object_as_dict_list(users)

@router.get("/users/{user_id}")  
async def get_user(user_id: int, db: Session = Depends(get_db)):
    # 查询单个对象
    user = db.query(User).filter(User.id == user_id).first()
    
    # 转换为字典
    return object_as_dict(user)
相关推荐
DONG9132 分钟前
《三驾马车:MySQL、MongoDB、Redis对比与融合实战》
数据库·redis·sql·mysql·mongodb·database
程序边界26 分钟前
从 Oracle 到 KingbaseES:企业信创改造的“抄作业”模板,直接套用!
数据库·oracle
funfan051737 分钟前
奇怪的“bug”--数据库的“隐式转换”行为
数据库·bug
Jasonakeke1 小时前
【重学MySQL】八十八、8.0版本核心新特性全解析
android·数据库·mysql
comeoffbest1 小时前
PostgreSQL 能存万物:从安装到高级功能实战
数据库·postgresql
时序数据说1 小时前
IoTDB如何解决海量数据存储难题?
大数据·数据库·物联网·时序数据库·iotdb
小楓12013 小时前
MySQL數據庫開發教學(二) 核心概念、重要指令
开发语言·数据库·mysql
花果山总钻风3 小时前
MySQL奔溃,InnoDB文件损坏修复记录
数据库·mysql·adb
TDengine (老段)4 小时前
TDengine IDMP 运维指南(管理策略)
大数据·数据库·物联网·ai·时序数据库·tdengine·涛思数据
Full Stack Developme4 小时前
PostgreSQL interval 转换为 int4 (整数)
数据库·postgresql