SQLALchemy

本博客参考资料:

1\] SQLALchemy官方文档:[地址](https://docs.sqlalchemy.org/en/14/orm/quickstart.html "地址") \[2\]《FastApi web开发入门、进阶与实践》 ## 一、SQLALchemy是什么 SQLALchemy是一个ORM(Object-Relational Mapping)库。本质上,ORM是对SQL语句的一种封装,它是对数据库表中列和行操作的一种对象映射。在某些情况下,使用ORM库时甚至不需要了解SQL,只需要通过对表映射出来的实体类模型进行操作就可实现对数据的增、删、改、查操作\[2\]。 ## 二、为什么需要ORM库 在以往,当我们需要操作数据库时,需要自己去编写增删改查sql语句,并且拼接参数。这样的做法存在以下问题:1. sql语句是字符串,需要人为检查,容易出错。2.重复编写sql语句。3.需要自己将查询结果与python对象映射,麻烦。4.需要掌握sql的语法。这个时候,大家就想有没有一种方法能够解决以上问题呢,不用重复编写sql语句,不用太多的sql语句的基础知识,能够直接操作本地对象的方式去操作数据库中的数据,所以ORM库就出现了。 ## 二、SQLALchemy怎么用 以下内容参考\[1\]。SQLALchemy目前有2.1、2.0、1.4、1.3几个版本,本文版本是用的2.0。 使用步骤: 1、定义映射类并创建数据表 2、获得session对象 3、构造sql语句 4、执行sql语句 5、获取返回结果 ### 2.1 定义映射类并创建数据表 代码如下: ```python from sqlalchemy import Column from sqlalchemy import ForeignKey from sqlalchemy import Integer from sqlalchemy import String from sqlalchemy.orm import declarative_base from sqlalchemy.orm import relationship # 创建所有模型类的基类,提供 ORM 映射的基础功能。 # 继承 Base 的类会自动注册到 Base.metadata.tables 中,后续可通过 #Base.metadata.create_all() 创建表 Base = declarative_base() class User(Base): # 指定数据库表名为 user_account __tablename__ = "user_account" # 定义主键字段,类型为 Integer,默认自增 id = Column(Integer, primary_key=True) name = Column(String(30)) fullname = Column(String) # 定义一对多关系(一个用户对应多个地址) addresses = relationship( "Address", back_populates="user", cascade="all, delete-orphan" ) # 调用print(user)时输出以下内容 def __repr__(self): return f"User(id={self.id!r}, name={self.name!r}, fullname={self.fullname!r})" class Address(Base): __tablename__ = "address" id = Column(Integer, primary_key=True) email_address = Column(String, nullable=False) user_id = Column(Integer, ForeignKey("user_account.id"), nullable=False) user = relationship("User", back_populates="addresses") def __repr__(self): return f"Address(id={self.id!r}, email_address={self.email_address!r})" ``` ```python from sqlalchemy import create_engine # sqlite:///:表示当前目录下的 SQLite 文件,如果没有,则自动创建 # echo=True:输出执行的 SQL 语句(调试用) # future=True:启用 SQLAlchemy 2.0 兼容模式 # 获取链接到数据库的引擎对象 engine = create_engine("sqlite:///example.db", echo=True, future=True) #其他常用数据库连接方式 mysql_engine = create_engine( # mysql+pymysql:使用 PyMySQL 驱动 "mysql+pymysql://user:password@localhost:3306/dbname", # pool_size:连接池大小(默认 5) pool_size=10, # max_overflow:允许临时超出 pool_size 的连接数 max_overflow=20, # pool_recycle:连接自动回收时间(秒),避免数据库断开 pool_recycle=3600, echo=True ) postgresql_engine = create_engine( "postgresql+psycopg2://user:password@localhost:5432/dbname", isolation_level="REPEATABLE READ", pool_pre_ping=True ) ``` ```python # 自动创建表,checkfirst为True时,表若存在,则不再创建,否则会报表已存在的错误,默认为True Base.metadata.create_all(engine, checkfirst = True) ``` ### 2.2 操作 #### 2.2.1 新增操作 ```python from sqlalchemy.orm import Session # with上下文管理,执行结束后自动释放session with Session(engine) as session: # 创建User对象 spongebob = User( name="spongebob", fullname="Spongebob Squarepants", addresses=[Address(email_address="spongebob@sqlalchemy.org")], ) sandy = User( name="sandy", fullname="Sandy Cheeks", addresses=[ Address(email_address="sandy@sqlalchemy.org"), Address(email_address="sandy@squirrelpower.org"), ], ) patrick = User(name="patrick", fullname="Patrick Star") # 批量添加 session.add_all([spongebob, sandy, patrick]) # 单个添加 # session.add(spongebob) # 提交事物 session.commit() ``` #### 2.2.2 查询操作 ```python from sqlalchemy.orm import Session with Session(engine) as session: # 构造sql语句 stmt = select(User).where(User.name.in_(["spongebob", "sandy"])) # 执行 result = session.execute(stmt) # result.scalars()获取内部数据 for user in result.scalars(): print(user) # 或者 for user in result.scalars().all(): print(user) ``` #### 2.2.3 删除操作 ```python with Session(engine) as session: # 直接按对象删 #session.delete(obj1) # 带条件删除 stmt = ( delete(User) .where(User.name == "squidward") # False:完全不同步会话。数据库操作后,会话中的对象可能包含过期数据 # 操作前查询数据库获取受影响主键,操作后同步会话中的对象,数据一致性高 # 操作前用 Python 评估会话中的对象是否符合条件 .execution_options(synchronize_session="fetch") ) session.execute(stmt) session.commit() ``` #### 2.2.4 更新 ```python with Session(engine) as session: stmt = ( update(User) .where(User.name == "sandy") .values(name="spongebob") .execution_options(synchronize_session="fetch") ) result = session.execute(stmt) session.commit() print(result.rowcount) ```

相关推荐
雄狮少年2 小时前
智能体服务封装
开发语言·windows·python
云天徽上2 小时前
【数据可视化-70】奶茶店销量数据可视化:打造炫酷黑金风格的可视化大屏
python·信息可视化·数据分析·数据可视化·pyecharts
IMER SIMPLE2 小时前
人工智能-python-OpenCV 图像基础认知与运用-图像的预处理(1)
人工智能·python·opencv
ku_code_ku2 小时前
Django关于ListView通用视图的理解(Cursor解释)
python·django·sqlite
荼蘼3 小时前
python爬虫实战-小案例:爬取苏宁易购的好评
开发语言·爬虫·python
运维小文3 小时前
初探贪心算法 -- 使用最少纸币组成指定金额
c++·python·算法·贪心算法
Eiceblue3 小时前
PDF转Markdown - Python 实现方案与代码
开发语言·vscode·python·pdf
Bruce_Liuxiaowei3 小时前
Python实现PDF按页分割:灵活拆分文档的技术指南
windows·python·pdf
烛九幽-子麟3 小时前
精通Python PDF裁剪:从入门到专业的三重境界
开发语言·python·pdf