SQLModel入门

目录

  • 概述
  • 快速开始
  • 官方教程
  • 简单使用样例

概述

SQLModel 是一个 ORM 框架,其基于 SQLAlchemy 和 Pydantic,其中 SQLALchemy 提供底层 ORM 能力,Pydantic 提供类型校验能力,SQLModel 中,一个 SQLModel model 既是一个 SQLAlchemy model 也是一个 Pydantic model。

SQLModel 的优势在于解决了 Python Web 开发中最大的痛点之一,ORM model 与 view model 重复问题。

通常,无论任何语言,Web 开发会将代码分层,常见的是分为三层:

  1. controller 层:将 view model 返回给前端,view model 是要返回的数据,会在这个层对入参或者出参进行参数校验,参数校验通常会定义一个 view model,view model 中定义各种参数限制
  2. service 层:是业务在代码层面的具体实现
  3. dao 层:负责与数据库交互,与具体业务无关,会使用 ORM 框架,定义一个一个 ORM model

从数据库查询数据,查询出来是一个 ORM model 对象,操作这个 ORM model 对象就相当于操作数据库,然而要返回的数据不会是一个单纯的 ORM model,通常是 ORM model 中的数据以及其他数据共同组成的一团数据,通常,会将 ORM nmodel 转为 dict 而后整体合并数据。等到要返回数据时,再将 dict 数据转为 view model 数据,最后由框架处理 view model 并将其返回(通常转为json后返回)。

上面的问题在于,controller 层与 dao 层都需要一个model,service 还要做合并,导致每两层之间必须都要做一次转换。

SQLModel 解决了这一问题,SQLModel 中,一个 SQLModel model 既是一个 SQLAlchemy model 也是一个 Pydantic model,由此将 controller 层 view model 和 dao 层 ORM model 统一,由此 service 层也可考虑使用 Pydantic model,或者还是使用 dict,Pydantic 原生支持转 dict。

快速开始

pip install sqlmodel

样例

from typing import Optionalfrom sqlmodel import Field, Session, SQLModel, create_engine# 对应数据库中一张表。继承 SQLModel,写明 table=True
class Hero(SQLModel, table=True):id: Optional[int] = Field(default=None, primary_key=True)name: strsecret_name: strage: Optional[int] = None# create_engine,是间接引用 SQLAlchemy 中的 create_engine 函数
engine = create_engine("mysql+pymysql://root:mYsql123456_@127.0.0.1:3306/dev")# 创建表
SQLModel.metadata.create_all(engine)# 创建 model 对象,既是 SQLAlchemy model 对象,也是 Pydantic 对象
hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)# 插入数据,Session 是 sqlalchemy.orm.Session 的子类
with Session(engine) as session:session.add(hero_1)session.add(hero_2)session.add(hero_3)session.commit()

官方教程

https://github.com/fastapi/sqlmodel
https://sqlmodel.tiangolo.com/learn/
https://sqlmodel.fastapi.org.cn/learn/

简单使用样例

import datetimefrom sqlmodel import Field, BigInteger, Integer, String, Boolean, DateTime, JSON, Session, insert, update, select, delete
from sqlmodel import SQLModel, create_engineclass BaseModel(SQLModel):id: int | None = Field(description="主键id", primary_key=True, sa_type=BigInteger,sa_column_kwargs=dict(comment="主键id"))is_delete: bool = Field(default=False, description="是否逻辑删除", sa_type=Boolean,sa_column_kwargs=dict(comment="是否逻辑删除"))updated_time: datetime.datetime | None = Field(description="更新时间", sa_type=DateTime,sa_column_kwargs=dict(comment="更新时间", onupdate=datetime.datetime.now,server_onupdate=""))created_time: datetime.datetime | None = Field(default_factory=datetime.datetime.now, description="创建时间",sa_type=DateTime,sa_column_kwargs=dict(comment="创建时间"))class User(BaseModel, table=True):  # 只有 table=True 的 model 会被创建为表__tablename__ = "tb_user"# 两个 32,一个用于 SQLAlchemy,一个用于 Pydanticname: str = Field(sa_type=String(32), max_length=32, sa_column_kwargs=dict(comment="用户名"))age: int = Field(sa_type=Integer, default=0, ge=0, le=200, sa_column_kwargs=dict(comment="年龄"))addresses: list[str] = Field(sa_type=JSON, default=[], sa_column_kwargs=dict(comment="地址列表"))other: dict = Field(sa_type=JSON, default={}, sa_column_kwargs=dict(comment="附加信息"))engine = create_engine("mysql+pymysql://root:mYsql123456_@127.0.0.1:3306/dev")
SQLModel.metadata.create_all(engine)
session = Session(engine)with session.begin():entity = User(name="张三", age=16, addresses=["beijing", "shanghai"])session.add(entity)with session.begin():entity = User(name="张三", age=16, addresses=["beijing", "shanghai"])statement = insert(User).values(entity.model_dump(exclude_none=True))  # 使用pydantic转换成字典(排除None是避免id传入None报错)session.exec(statement)with session.begin():entity = User(id=5, name="赵四", age=17, addresses=["beijing"])statement = update(User).where(User.id == 5).values(entity.model_dump())session.exec(statement)with session.begin():statement = select(User).where(User.name == "赵四")result = session.exec(statement).all()print(result)with session.begin():statement = delete(User).where(User.id == 6)session.exec(statement)

以使用者的角度看,SQLModel 整体上对 Pydantic 和 SQLAlchemy 有了一个大致封装,但是目前 v0.0.22 版本中有很多细节感觉做的不够细致导致有一种Pydantic 和 SQLAlchemy 简单缝合的感觉,比如一些类型提示不兼容导致静态检查报错,一些 SQLModel 中的 SQLALchemy 参数比较含糊,需要到 SQLAlachemy 中寻找具体参数进行补充。不过不影响具体执行。Python 生态中需要一个 view model 与 ORM model 统一的框架,静待这个库成熟。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/69057.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分割链表

题目: 给定一个链表的头节点和一个特定值 x ,请你对链表进行分隔,使得所有小于 x 的节点都出现在大于等于 x 的节点之前 ( 链表中节点数为[0,500],不要求链表的顺序 ) 思路一:在原链表上进行修改 在原链表…

DeepSeek-R1:开源机器人智能控制系统的革命性突破

目录 引言 一、DeepSeek-R1 的概述 1.1 什么是 DeepSeek-R1? 1.2 DeepSeek-R1 的定位 二、DeepSeek-R1 的核心特性 2.1 实时控制能力 2.2 多传感器融合 2.3 路径规划与导航 2.4 人工智能集成 2.5 开源与模块化设计 2.6 跨平台支持 三、DeepSeek-R1 的技术…

starrocks最佳实践、行业实践

最佳实践 starrocks最佳实践 最佳实践集合 Bitmap索引适用场景和最佳实践 行业实践 行业实践

响应式编程_01基本概念:前世今生

文章目录 引言响应式编程的技术优势全栈式响应式编程从传统开发模式到异步执行技术Web 请求与 I/O 模型异步调用的实现技术回调Future机制 响应式编程实现方法观察者模式发布-订阅模式数据流与响应式 响应式宣言和响应式系统 引言 大流量、高并发的访问请求的项目,…

一文速览DeepSeek-R1的本地部署——可联网、可实现本地知识库问答:包括671B满血版和各个蒸馏版的部署

前言 自从deepseek R1发布之后「详见《一文速览DeepSeek R1:如何通过纯RL训练大模型的推理能力以比肩甚至超越OpenAI o1(含Kimi K1.5的解读)》」,deepseek便爆火 爆火以后便应了“人红是非多”那句话,不但遭受各种大规模攻击,即便…

Vue.js 使用组件库构建 UI

Vue.js 使用组件库构建 UI 在 Vue.js 项目中,构建漂亮又高效的用户界面(UI)是很重要的一环。组件库就是你开发 UI 的好帮手,它可以大大提高开发效率,减少重复工作,还能让你的项目更具一致性和专业感。今天…

队列 + 宽搜(4题)

目录 1.n叉树的层序遍历 2.二叉树的锯齿形层序遍历 3.二叉树的最大宽度 4.在每个树行中找最大值 1.n叉树的层序遍历 429. N 叉树的层序遍历 - 力扣(LeetCode) 我们只需要把某个节点出队的时候把它的孩子节点添加进来即可。 出队的次数就是最开始队列…

计算机基础知识(第二篇)

计算机基础知识(第二篇) 嵌入式技术 嵌入式技术 特点:专用性、实时性、低成本、可靠性、体积小 应用:汽车电子、家用电器、通信设备、安防监控、工业自动化、医疗设备 体系结构: 冯诺依曼结构:传统计…

HTML 标题

HTML 标题 引言 HTML(超文本标记语言)是构建网页的基础,而标题则是网页中不可或缺的元素。标题不仅能够帮助用户快速了解网页内容,还能够对搜索引擎优化(SEO)产生重要影响。本文将详细介绍HTML标题的用法…

惰性函数【Ⅱ】《事件绑定的自我修养:从青铜到王者的进化之路》

【Ⅱ】《事件绑定的自我修养:从青铜到王者的进化之路》 1. 代码功能大白话(给室友讲明白版) // 青铜写法:每次都要问浏览器"你行不行?" function addEvent青铜版(element, type, handler) {if (window.add…

sentinel的限流原理

Sentinel 的限流原理基于 流量统计 和 流量控制策略,通过动态规则对系统资源进行保护。其核心设计包括以下几个关键点: 流量统计模型:滑动时间窗口 Sentinel 使用 滑动时间窗口算法 统计单位时间内的请求量,相比传统的固定时间窗…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.28 NumPy+Matplotlib:科学可视化的核心引擎

2.28 NumPyMatplotlib:科学可视化的核心引擎 目录 #mermaid-svg-KTB8Uqiv5DLVJx7r {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-KTB8Uqiv5DLVJx7r .error-icon{fill:#552222;}#mermaid-svg-KTB8Uqiv5…

upload-labs安装与配置

前言 作者进行upload-labs靶场练习时,在环境上出了很多问题,吃了很多苦头,甚至改了很多配置也没有成功。 upload-labs很多操作都是旧时代的产物了,配置普遍都比较老,比如PHP版本用5.2.17(还有中间件等&am…

【OS】AUTOSAR架构下的Interrupt详解(下篇)

目录 3.代码分析 3.1中断配置代码 3.2 OS如何找到中断处理函数 3.3 Os_InitialEnableInterruptSources实现 3.4 Os_EnableInterruptSource 3.5 DisableAllInterrupts 3.5.1Os_IntSuspendCat1 3.5.2 Os_InterruptDisableAllEnter 3.5.3 Disable二类中断 3.5.4 Disable一…

Nginx知识

nginx 精简的配置文件 worker_processes 1; # 可以理解为一个内核一个worker # 开多了可能性能不好events {worker_connections 1024; } # 一个 worker 可以创建的连接数 # 1024 代表默认一般不用改http {include mime.types;# 代表引入的配置文件# mime.types 在 ngi…

RabbitMQ快速上手及入门

概念 概念: publisher:生产者,也就是发送消息的一方 consumer:消费者,也就是消费消息的一方 queue:队列,存储消息。生产者投递的消息会暂存在消息队列中,等待消费者处理 exchang…

DeepSeek本地部署的一些问题记录

1、模型怎么不保存到C盘:关掉ollama之后,设置环境变量:OLLAMA_MODELS,环境变量的地址,改为你想要的地址,参考文章: https://blog.csdn.net/u012151594/article/details/142062199 2、ollama rm…

leetcode_680 验证回文串

1. 题意 在最多去掉一个字符的情况下,判断一个字符串是否是回文串。 2. 题解 双指针 两个指针i j分别指向字符串开头和结尾,如果相同则同时向中间移动;如果不同则判断剩下的字符串,去掉头或者去掉尾能否成一回文串。 i 0j sz…

java使用pcap4j进行报文发送和接收

1、pcap4j框架使用的驱动Npcap需要进行安装 2、获取自己window电脑的mac地址设备 在cmd中使用的命令是getmac 使用程序获取服务器本身的mac地址 import org.pcap4j.core.PcapNativeException; import org.pcap4j.core.PcapNetworkInterface; import org.pcap4j.core.Pcaps;…

糖化之前,为什么要进行麦芽粉碎?

糖化的目的是将麦芽中的淀粉转化为可发酵性的糖分,而糖化之前,进行麦芽粉碎是确保糖化效果的关键步骤。本文天泰将阐述麦芽粉碎的重要性及其对酿造过程的影响。 一、麦芽粉碎的目的 增加酶的作用面积:麦芽中的淀粉和蛋白质等物质需要通过酶…