SQLModel入门

devtools/2025/2/5 15:20:05/

目录

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

概述

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.ppmy.cn/devtools/156303.html

相关文章

Linux网络 | 理解TCP面向字节流、打通socket与文件的关系

前言:我们经常说TCP是面向字节流的, TCP是面向字节流的。 但是, 到底是什么事面向字节流呢? 另外, 我们知道sockfd其实就是文件fd。 但是,为什么sockfd是文件fd呢? 这些问题都在本节内容中的到回…

如何安装PHP依赖库 更新2025.2.3

要在PHP项目中安装依赖,首先需要确保你的系统已经安装了Composer。Composer是PHP的依赖管理工具,它允许你声明项目所需的库,并管理它们。以下是如何安装Composer和在PHP项目中安装依赖的步骤: 一. 安装Composer 对于Windows用户…

解锁C/C++:链表数据结构的奇幻之旅

目录 一、引言二、链表基础概念2.1 链表是什么2.2 链表的类型三、C 语言实现链表3.1 定义链表节点3.2 创建链表3.3 链表操作3.3.1 遍历链表3.3.2 插入节点3.3.3 删除节点3.3.4 查找节点3.4 完整示例代码四、C++ 实现链表4.1 定义链表节点类4.2 创建链表4.3 链表操作4.3.1 遍历链…

proxmox创建虚拟机

概述: proxmox服务器已经搭建完成从Proxmox VE开始:安装与配置指南,下面准备搭建一下自己的实验环境。创建虚拟机是第一步,因此本篇博客将详细介绍如何在 Proxmox 上创建虚拟机,包括通过控制台高效地创建虚拟机和使用…

MVC 文件夹:架构之美与实际应用

MVC 文件夹:架构之美与实际应用 引言 MVC(Model-View-Controller)是一种设计模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种架构模式不仅提高了代码的可维护性和可扩展性,而且使得开发流程更加清晰。本文将深入探讨MVC文…

开源2+1链动模式AI智能名片S2B2C商城小程序:突破流量与创意困境的新路径

摘要:本文深入剖析当前互联网行业中流量集中于巨头以及创意边际效应递减的困境,并探讨开源21链动模式AI智能名片S2B2C商城小程序在应对这些困境时所展现的独特优势与应用策略。通过对行业现状的分析以及该小程序功能特点的研究,旨在为企业在艰…

【Proteus】NE555纯硬件实现LED呼吸灯效果,附源文件,效果展示

本文通过NE555定时器芯片和简单的电容充放电电路,设计了一种纯硬件实现的呼吸灯方案,并借助Proteus仿真软件验证其功能。方案无需编程,成本低且易于实现,适合电子爱好者学习PWM(脉宽调制)和定时器电路原理。 一、呼吸灯原理与NE555功能分析 1. 呼吸灯核心原理 呼吸灯的…

【大模型LLM面试合集】大语言模型架构_llama系列模型

llama系列模型 1.LLama 1.1 简介 Open and Efficient Foundation Language Models (Open但没完全Open的LLaMA) 2023年2月,Meta(原Facebook)推出了LLaMA大模型,使用了1.4T token进行训练,虽然最大模型只有65B&…