
在构建现代web api时,将数据库中的数据(通常以orm模型对象形式存在)转换为前端可理解的json格式是一个核心需求。对于简单的sqlalchemy模型,直接将其属性映射到字典可能看似可行。然而,当模型涉及继承、一对多或多对多关系时,这种简单方法会遇到局限,例如无法自动包含关联表的数据。本文将介绍几种高效且推荐的方法,以解决sqlalchemy模型,特别是包含复杂关系的模型,到json的序列化问题。
SQLAlchemy-serializer 是一个为 SQLAlchemy 模型提供便捷序列化功能的扩展。它通过一个 SerializerMixin 混合类,允许模型直接调用 to_dict() 方法来生成字典表示,并支持深度序列化和循环引用控制。
pip install SQLAlchemy-serializer
import json
from sqlalchemy import ForeignKey, create_engine
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, sessionmaker
from sqlalchemy_serializer import SerializerMixin
# 基础模型类,继承SerializerMixin
class Base(DeclarativeBase, SerializerMixin):
pass
class Project(Base):
__tablename__="projects"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
owner_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
class User(Base):
__tablename__="users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
projects: Mapped[list[Project]] = relationship(backref="owner")
# 使用 serialize_rules 避免循环引用,例如在序列化项目时不再序列化项目的owner
serialize_rules = ('-projects.owner',)
# 数据库初始化与会话管理
engine = create_engine("sqlite://")
Base.metadata.create_all(engine)
session_maker = sessionmaker(bind=engine)
with session_maker() as session:
user = User(name="User1")
user.projects.append(Project(name="Project 1"))
user.projects.append(Project(name="Project 2"))
session.add(user)
session.commit()
session.refresh(user) # 刷新对象以加载关联数据
# 序列化为字典并转换为JSON字符串
print(json.dumps(user.to_dict(), indent=4)){
"id": 1,
"projects": [
{
"id": 1,
"name": "Project 1",
"owner_id": 1
},
{
"id": 2,
"name": "Project 2",
"owner_id": 1
}
],
"name": "User1"
}Pydantic 是一个基于类型提示的Python数据验证和设置管理库。它不仅能用于验证输入数据,还能作为强大的序列化工具,将复杂的Python对象(包括SQLAlchemy模型)转换为标准化的字典或JSON。
pip install pydantic sqlalchemy
from sqlalchemy import ForeignKey, create_engine
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, sessionmaker
from pydantic import BaseModel, ConfigDict
# SQLAlchemy 模型定义
class Base(DeclarativeBase):
pass
class Project(Base):
__tablename__="projects"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
owner_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
class User(Base):
__tablename__="users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
projects: Mapped[list[Project]] = relationship(backref="owner")
# Pydantic 模型定义
class ProjectScheme(BaseModel):
# 启用从ORM对象读取属性
model_config = ConfigDict(from_attributes=True)
id: int
name: str
class UserScheme(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
name: str
projects: list[ProjectScheme] # 关联字段也需要对应的Pydantic模型
# 数据库初始化与会话管理
engine = create_engine("sqlite://")
Base.metadata.create_all(engine)
session_maker = sessionmaker(bind=engine)
with session_maker() as session:
user = User(name="User1")
user.projects.append(Project(name="Project 1"))
user.projects.append(Project(name="Project 2"))
session.add(user)
session.commit()
session.refresh(user)
# 通过Pydantic模型验证并序列化SQLAlchemy对象
user_json = UserScheme.model_validate(user).model_dump_json(indent=4)
print(user_json){
"id": 1,
"name": "User1",
"projects": [
{
"id": 1,
"name": "Project 1"
},
{
"id": 2,
"name": "Project 2"
}
]
}SQLModel 是一个由 FastAPI 作者开发的库,它旨在简化数据库交互,通过将 SQLAlchemy 和 Pydantic 的优势结合起来,允许你用一个模型定义同时作为数据库表和数据验证/序列化模型。
pip install sqlmodel
from typing import Optional
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlmodel import SQLModel, Field, Relationship
# 定义项目基础模型
class ProjectBase(SQLModel):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
# 定义项目数据库模型
class Project(ProjectBase, table=True):
__tablename__="projects"
owner_id: Optional[int] = Field(default=None, foreign_key="users.id")
owner: "User" = Relationship(back_populates="projects") # 定义反向关系
# 定义用户基础模型
class UserBase(SQLModel):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
# 定义用户数据库模型
class User(UserBase, table=True):
__tablename__="users"
projects: list[Project] = Relationship(back_populates="owner") # 定义关联关系
# 定义用户输出模型 (用于序列化,可以控制输出字段)
class UserOutput(UserBase):
projects: list[ProjectBase] = [] # 关联字段使用ProjectBase以避免循环或精简输出
# 数据库初始化与会话管理
engine = create_engine("sqlite://")
SQLModel.metadata.create_all(engine)
session_maker = sessionmaker(bind=engine)
with session_maker() as session:
user = User(name="User1")
user.projects.append(Project(name="Project 1"))
user.projects.append(Project(name="Project 2"))
session.add(user)
session.commit()
session.refresh(user)
# 通过输出模型验证并序列化SQLModel对象
print(UserOutput.model_validate(user).model_dump_json(indent=4)){
"id": 1,
"name": "User1",
"projects": [
{
"id": 1,
"name": "Project 1"
},
{
"id": 2,
"name": "Project 2"
}
]
}选择哪种序列化方案取决于你的项目需求和偏好:
无论选择哪种方案,都应注意:
通过上述方法,你可以有效地将复杂的 SQLAlchemy 模型转换为结构良好、易于消化的 JSON 格式,从而构建健壮且高效的后端API。
以上就是SQLAlchemy 模型高效转换为 JSON:多方案深度解析的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号