SQLAlchemy ORM - 声明映射

SQLAlchemy 的对象关系映射器 API 的主要目的是便于将用户定义的 Python 类与数据库表关联,并将这些类的对象与相应表中的行关联。对象和行的状态变化同步匹配。SQLAlchemy 允许根据用户定义的类及其定义的关系来表达数据库查询。

ORM 构建在 SQL 表达式语言之上。它是一种高级且抽象的使用模式。事实上,ORM 是表达式语言的一种应用用法。

虽然可以仅使用对象关系映射器构建成功的应用程序,但有时使用 ORM 构建的应用程序可能会在需要特定数据库交互时直接使用表达式语言。

声明映射

首先,调用 create_engine() 函数来设置引擎对象,随后使用该引擎对象执行 SQL 操作。该函数有两个参数,一个是数据库的名称,另一个是 echo 参数,设置为 True 时将生成活动日志。如果不存在,则将创建数据库。在以下示例中,创建了一个 SQLite 数据库。

from sqlalchemy import create_engine
engine = create_engine('sqlite:///sales.db', echo = True)

当调用 Engine.execute() 或 Engine.connect() 等方法时,Engine 会与数据库建立真正的 DBAPI 连接。然后使用它来发出不直接使用 Engine 的 SQLORM;相反,它由 ORM 在后台使用。

对于 ORM,配置过程从描述数据库表开始,然后定义将映射到这些表的类。在 SQLAlchemy 中,这两个任务一起执行。这是通过使用声明式系统完成的;创建的类包含指令来描述它们映射到的实际数据库表。

基类在声明系统中存储类和映射表的目录。这被称为声明基类。通常,在通常导入的模块中只有一个此基类的实例。declarative_base() 函数用于创建基类。此函数在 sqlalchemy.ext.declarative 模块中定义。

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

一旦声明了基类,就可以根据它定义任意数量的映射类。以下代码定义了一个 Customer 类。它包含要映射到的表以及其中列的名称和数据类型。

class Customers(Base):
   __tablename__ = 'customers'
   
   id = Column(Integer, primary_key = True)
   name = Column(String)
   address = Column(String)
   email = Column(String)

Declarative 中的类必须具有 __tablename__ 属性,以及至少一个作为主键一部分的 Column。Declarative 用称为 descriptors 的特殊 Python 访问器替换所有 Column 对象。此过程称为检测,它提供在 SQL 上下文中引用表的方法,并允许持久化和从数据库加载列的值。

此映射类与普通 Python 类一样,具有符合要求的属性和方法。

Declarative 系统中有关类的信息称为表元数据。SQLAlchemy 使用 Table 对象来表示 Declarative 创建的特定表的此信息。Table 对象是根据规范创建的,并通过构造 Mapper 对象与类相关联。此映射器对象不直接使用,但在内部用作映射类和表之间的接口。

每个 Table 对象都是称为 MetaData 的更大集合的成员,此对象可使用声明性基类的 .metadata 属性获得。MetaData.create_all() 方法将我们的 Engine 作为数据库连接的源传入。对于尚未创建的所有表,它会向数据库发出 CREATE TABLE 语句。

Base.metadata.create_all(engine)

下面给出了创建数据库和表以及映射 Python 类的完整脚本−

from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
engine = create_engine('sqlite:///sales.db', echo = True)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class Customers(Base):
   __tablename__ = 'customers'
   id = Column(Integer, primary_key=True)

   name = Column(String)
   address = Column(String)
   email = Column(String)
Base.metadata.create_all(engine)

执行时,Python 控制台将回显正在执行的以下 SQL 表达式 −

CREATE TABLE customers (
   id INTEGER NOT NULL,
   name VARCHAR,
   address VARCHAR,
   email VARCHAR,
   PRIMARY KEY (id)
)

如果我们使用 SQLiteStudio 图形工具打开 Sales.db,它会显示其中具有上述结构的客户表。

客户表