SQLALchemy

本博客参考资料:

1 SQLALchemy官方文档:地址

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)
相关推荐
万笑佛24 分钟前
Python 实现Kafka SASL认证生产消费
python
m0_617493942 小时前
Python OpenCV 透视变换(Perspective Transform)详解与实战
开发语言·python·opencv
小李不困还能学2 小时前
PyCharm下载安装与配置教程
ide·python·pycharm
博观而约取厚积而薄发2 小时前
Pytest 从入门到精通,一篇就够(超详细实战教程)
python·测试工具·单元测试·自动化·pytest
imzed2 小时前
使用 Playwright + Pytest 构建 Web UI 自动化测试框架
python·自动化·pytest
普通网友2 小时前
pytest一些常见的插件
开发语言·python·pytest
时空系2 小时前
Python 高性能高压缩打包器 —— 基于 JianPy 语义分析引擎
python
cndes3 小时前
给Miniconda换源,让包下载更迅速
开发语言·python
Metaphor6923 小时前
使用 Python 添加、隐藏和删除 PDF 图层
python·pdf·图层