SQLAlchemy 的基本图像

SQLAlchemy 的基本图像

SQLAlchemy 概述

在标准情况下,当我们想操纵一个数据库,比如建表或者进行数据的增删查改时,需要在特定的平台执行 SQL 语句,比如在 MySQL-client 上执行 CREATE DATABASE 数据库名; 等等操作。但在实际开发过程中,一般不会单独使用数据库,数据库都是作为程序整体流程的一部分,用于储存程序的相关数据或中间结果。这个时候,希望能够在程序中直接操纵数据库。此时,就需要进行对象关系映射(Object-relational mapping, ORM)。在 Python 开发中,SQLAlchemy 是最流行的 ORM 框架之一,它可以将数据库操作抽象成 Python 对象,使得可以像操作 Python 类一样执行数据库的建表以及增删查改等操作。

SQLAlchemy 有两个核心组成部分:SQLAlchemy Core 构建了 SQL 表达式的底层语法系统;SQLAlchemy ORM 提供了 SQL 表/数据与 Python 类/对象之间的映射能力。总的来说,SQLAlchemy 就是提供了可以使用纯 Python 代码来完成数据库结构的定义和数据操作能力的一种工具,这使得我们更方便地管理数据表模型结构和维护业务逻辑。

SQLAlchemy 的核心逻辑结构

graph 
    A["DATABASE_URL"] --> B["create_engine()"]
    B --> C[Engine]
    C --> D["declarative_base()"]
    D --> E[ORM 模型类
User / Simulation 等] E --> F["Base.metadata.create_all(engine)"] C --> G["sessionmaker(bind=engine)"] G --> H[Session] H --> I[CRUD 操作
增删改查/事务提交]

SQLAlchemy 使用的基本图像就是围绕 Engine 展开的 ORM 和 Session 两条支线。Engine 负责构建与数据库之间的连接,是唯一实际与数据库通信的对象。SQLAlchemy 中的所有操作都不会直接操作数据库本身,全部都是通过 Engine 进行交互。通过 create_engine(DATABASE_URL) 可以创建一个 Engine 实例,建立与指定数据库的连接。围绕 Engine 通常有两类操作:一类是通过 ORM 描述数据库表结构并创建表,另一类是通过 Session(会话)进行数据库的数据操作。

在建表方面,SQLAlchemy 的基本流程是首先通过 Base = declarative_base() 创建所有 ORM 模型的基类,所有的 ORM 类都需要继承它,并通过类变量描述表结构。模型类定义完成后,通过 Base.metadata.create_all(engine) 与数据库引擎连接,把模型信息同步到数据库中,从而创建对应的表结构。Session 是数据库操作的“临时事务会话”,所有数据操作都需要通过 Session 执行。使用 Session 相当于开启一个数据库连接通道,操作完成后会话关闭,防止连接泄露或资源占用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import declarative_base, sessionmaker

# 1. 创建引擎(唯一和数据库通信的核心)
engine = create_engine("sqlite:///demo.db")

# 2. 创建 ORM 基类
Base = declarative_base()

# 3. 定义模型(只和 Base 有关系,还没和数据库接触)
class User(Base):
__tablename__ = "user"
id = Column(Integer, primary_key=True)
name = Column(String)

# 4. 使用 Base.metadata.create_all(engine) 创建表 → 把模型和 Engine 连接
Base.metadata.create_all(engine)

# 5. 创建 Session 工厂
Session = sessionmaker(bind=engine)
session = Session()

# 6. 用 Session 操作数据库(insert/select/delete 等)
session.add(User(name="Alice"))
session.commit()
session.close()

在 SQLAlchemy 中,使用完 Session 后,应调用 session.close() 关闭会话,以释放数据库连接资源。就像 Python 中打开和关闭文件的操作,Session 也可以在 with 语句中实现自动关闭:

1
2
3
with Session(engine) as session:
session.add(User(name="Alice"))
session.commit()

或者也可以自定义一个装饰器,自动创建 Session 并在函数结束时关闭它,从而统一管理所有业务函数中的数据库会话:

1
2
3
4
5
6
7
8
9
10
11
12
def with_session(func):
def wrapper(*args, **kwargs):
session = SESSION()
try:
return func(session, *args, **kwargs)
finally:
session.close()
return wrapper

@with_session
def get_user(session, id):
return session.query(User).get(id)

项目实践

在项目实践中,可以把数据库连接信息以及其他配置统一写入配置文件 config.py

1
2
3
# config.py
class Config:
DATABASE_URL = "sqlite:///mydb.db"

在模型定义文件中,可以将 ORM 模型类、enginesession 一并集中处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
# models.py
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import declarative_base, sessionmaker

Base = declarative_base()

class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String)

engine = create_engine("sqlite:///mydb.db")
Session = sessionmaker(bind=engine)

如果项目更复杂,可以进一步拆分模块,将配置文件、模型类、数据库连接等分开放置。