讲师中心 微信公众号
AI工具推荐 视频效率加速

Python sqlmodel 的 ORM + Pydantic 结合

千明酱_4080

千明酱_4080

发布时间:2026-02-16 15:27:01

|

761人浏览过

|

来源于php中文网

原创

SQLModel中应优先用Field定义模型,它自动桥接Pydantic验证与SQLAlchemy列类型;FieldInfo仅用于底层定制。混用Column会忽略Field参数,Relationship需显式配置lazy策略才能序列化关联数据。

python sqlmodel 的 orm + pydantic 结合

SQLModel 模型定义时,Field 和 FieldInfo 到底怎么选?

SQLModel 的核心混淆点就在这儿:它把 Pydantic 的 Field(来自 pydantic.v1 或 pydantic v2)和 SQLAlchemy 的列定义混在了一起。你写 name: str = Field(..., max_length=50),看起来像 Pydantic 验证,其实 max_length 会被自动转成 String(50) —— 但仅当字段类型是 str 且没显式用 Column 包裹时才生效。

  • 如果你用了 Column(String(50)),Field(max_length=50) 就被完全忽略,Pydantic 验证也不触发
  • Field(default=None) 和 Field(default_factory=lambda: uuid4()) 是安全的,会同时影响 ORM 默认值和 Pydantic 初始化逻辑
  • Field(exclude=True) 只作用于 Pydantic 序列化(比如 .model_dump()),对数据库字段无影响
from sqlmodel import SQLModel, Field
from typing import Optional
<p>class User(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str = Field(..., max_length=50)  # ✅ 自动生成 String(50),且校验长度
email: str = Field(..., sa_column=Column(String(100)))  # ❌ max_length 失效,只认 Column 定义</p>

查询结果转 Pydantic 模型时,为什么 .model_dump() 报 AttributeError: 'User' object has no attribute '__pydantic_core_schema__'?

这不是你的模型写错了,而是你混用了 SQLModel 模型和纯 Pydantic 模型的序列化路径。SQLModel 类本身继承自 Pydantic BaseModel,但它在 v0.0.19+ 后默认启用 pydantic.v2,而老项目可能还卡在 v1 兼容模式;更常见的是:你从数据库查出来的对象是 ORM 实例,带延迟加载属性(比如 user.posts),直接调 .model_dump() 会尝试序列化未加载的关联字段,触发 lazy loading 异常,然后错误被掩盖成上面那个 schema 错误。

  • 确保 SQLModel 版本 ≥ 0.0.19,并显式指定 pydantic_version="2"(如果手动控制)
  • 查询后立刻用 sqlmodel.sqlmodel_session.expunge_all() 或 session.refresh(obj) 清理状态,避免延迟加载干扰
  • 更稳妥的做法:用 model_validate(obj.<strong>dict</strong>)(v2)或 parse_obj(obj.<strong>dict</strong>)(v1)绕过 ORM 属性代理机制

别直接对 ORM 实例调 .model_dump(mode="json"),尤其当模型含 Relationship 时——它大概率会崩。

Relationship 字段在 Pydantic 输出里总是 None,即使数据库有数据

SQLModel 的 Relationship 默认不自动加载关联数据,它只是声明“这儿有个外键关系”,行为上等价于 SQLAlchemy 的 relationship(lazy="selectin") 需要你主动配置。所以哪怕数据库里 user.profile_id 不为空,user.profile 在 Pydantic dump 里也还是 None,因为 ORM 根本没去查那张表。

macOS UI 自动化技能包 —— 用 Python 控制你的 Mac
macOS UI 自动化技能包 —— 用 Python 控制你的 Mac

让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限

下载

立即学习“Python免费学习笔记(深入)”;

  • 在 Relationship 中显式加 sa_relationship_kwargs={"lazy": "joined"}(适合一对一)或 {"lazy": "selectin"}(一对多)
  • 如果只想在序列化时包含关联,别依赖 Relationship 自动填充,改用 model_computed_field + @computed_field 手动拼装(v2),或者用 model_config = {"include": {"profile": True}} 配合预加载
  • 注意:加了 lazy="joined" 会导致每次查 User 都 JOIN Profile 表,N+1 问题换成了笛卡尔积风险

Relationship 不是“自动关联”,它只是个声明。想输出关联数据,得自己告诉 SQLModel “现在就要查”。

用 create_engine 连接 PostgreSQL 时,pool_pre_ping=True 为什么让 FastAPI 接口变慢?

pool_pre_ping=True 的本意是每次取连接前发一个 SELECT 1 检查连通性,防止用到已断开的连接。但它在高并发下会造成明显延迟,尤其当数据库负载高、网络抖动或连接池空闲连接多时,每个请求都多一次 round-trip。

  • 生产环境更推荐 pool_recycle=3600(一小时强制重连)+ pool_pre_ping=False,再配合监控告警(如 pg_stat_activity 中 idle in transaction 超时)
  • 如果必须用 pre_ping,至少加上 pool_use_lifo=True,让连接池优先复用刚释放的连接(减少新连接建立概率)
  • FastAPI 的 Depends 中每次新建 session?那 pre_ping 会每请求触发一次——应该用单例 engine + request-scoped session,而不是 per-request engine

pre_ping 是防错手段,不是性能方案。线上压测时关掉它,看错误率是否真升高;如果没升,说明网络和 DB 稳定,没必要为小概率问题牺牲确定性延迟。

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2255

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3642

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1216

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

4199

2025.09.10

Python FastAPI异步API开发_Python怎么用FastAPI构建异步API
Python FastAPI异步API开发_Python怎么用FastAPI构建异步API

Python FastAPI 异步开发利用 async/await 关键字,通过定义异步视图函数、使用异步数据库库 (如 databases)、异步 HTTP 客户端 (如 httpx),并结合后台任务队列(如 Celery)和异步依赖项,实现高效的 I/O 密集型 API,显著提升吞吐量和响应速度,尤其适用于处理数据库查询、网络请求等耗时操作,无需阻塞主线程。

119

2025.12.22

Python 微服务架构与 FastAPI 框架
Python 微服务架构与 FastAPI 框架

本专题系统讲解 Python 微服务架构设计与 FastAPI 框架应用,涵盖 FastAPI 的快速开发、路由与依赖注入、数据模型验证、API 文档自动生成、OAuth2 与 JWT 身份验证、异步支持、部署与扩展等。通过实际案例,帮助学习者掌握 使用 FastAPI 构建高效、可扩展的微服务应用,提高服务响应速度与系统可维护性。

574

2026.02.06

Python Web框架FastAPI 全栈开发教程合集
Python Web框架FastAPI 全栈开发教程合集

以 FastAPI 为核心,讲解现代 Python Web API 的高效开发方式,涵盖路由定义与路径参数/查询参数/请求体绑定、Pydantic 模型的数据校验与序列化、依赖注入(Depends)系统的分层设计、中间件与 CORS 配置、OAuth2 + JWT 认证流程、后台任务(BackgroundTasks)、WebSocket 实时通信、SQLAlchemy 异步 ORM 集成、自动生成 OpenAPI/Swagger 交互文

716

2026.05.09

Python FastAPI异步微服务与高性能接口设计
Python FastAPI异步微服务与高性能接口设计

本专题聚焦 Python FastAPI 框架在高性能接口与微服务开发中的应用,讲解异步请求处理、依赖注入机制、路由设计、数据库异步操作以及接口性能优化策略。结合实际项目案例,帮助开发者构建高并发、低延迟的现代化后端服务架构。

599

2026.06.16

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

0

2026.11.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn