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)
相关推荐
欢呼的太阳8 小时前
数据库设计Step by Step (10)——范式化
服务器·数据库·oracle
喜欢的名字被抢了9 小时前
MySQL基础入门:从零理解数据库与SQL
数据库·mysql·教程
Elastic 中国社区官方博客10 小时前
如何比较两个 Elasticsearch 索引并找出缺失的文档
大数据·运维·数据库·elasticsearch·搜索引擎
DLYSB_10 小时前
生命通道:如何用 HIS 医疗系统直连网络声光终端,打造“零延误”的危急值响应网关?
java·网络·数据库·报警灯
儒雅的大叔10 小时前
MySQL数据库InnoDB数据恢复工具使用总结
数据库·mysql·adb
观远数据11 小时前
ChatBI选型对比:从意图识别到SQL修复,六个维度打分决定是否值得投产
数据库·人工智能·sql
嘉&年华11 小时前
【第008篇】通过dexp和dimp命令导出和导入dmp文件(适用于达梦数据库)
数据库·sql
哥是强混12 小时前
Means:基于 .NET 10 打造的开源自部署 S3 兼容对象存储服务
网络·数据库·.net
ffqws_12 小时前
redis面试:如何保证双写一致
数据库·redis·缓存
水无痕simon13 小时前
6 数据库同义词
数据库