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)
相关推荐
leisoo80977 小时前
100GBA股股票数据怎么存ClickHouseRedisMySQLJSON完整对比
大数据·linux·服务器·开发语言·python
WangYan20227 小时前
基于XGBoost与AI的生态—地学多源数据建模:植被与土地利用识别、土壤碳氮空间预测、生物多样性驱动机制、土壤微生物功能预测、生态退化与风险识别
python·机器学习·xgboost
金銀銅鐵9 小时前
[Python] 借助 turtle 逐字展示唐诗《金缕衣》
python
java1234_小锋9 小时前
【免费】基于Python的微信小程序网约车(打车,在线叫车,移动出行)系统(FastAPI+Vue3) 锋哥原创出品,必属精品
微信小程序·小程序·fastapi·网约车系统·在线叫车系统
Python大数据分析@11 小时前
使用大模型MCP采集数据,爬虫已经无门槛
python·网络爬虫
quantdash_cc11 小时前
告别自建 Requests/BS4 网页爬虫:基于 QuantDash 搭建零维保的高性能量化行情流水线
开发语言·爬虫·python·pandas·量化·quantdash
65岁退休Coder12 小时前
LangChain v1.3.4 笔记 - 07 补充:链式调用 LCEL
后端·python·langchain
卷无止境12 小时前
FastAPI 部署在 Nginx 后面到底该怎么配
后端·python
半亩码田12 小时前
C#转Python第3.1篇:Python 的 class 没有访问修饰符?面向对象的另一条路
开发语言·python·c#
Wzx19801213 小时前
python沙箱和docker沙箱你选对了吗?
开发语言·python·docker