Schema
Schema 即模式,更好的翻译应该是表架构或表元数据。构建 Schema 实际上是 ORM 的核心,他通过面向对象的语句来描述关系型数据库。SQLALchemy 中提供了Schema Definition Language来描述数据库的模式。
组件
SQLAlchemy 为关系型数据库的各个组件提供了对应的类对象:
- MetaData: 数据库即表(Table)的集合
- Table: 表
- Column: 列
这三个对象也是关系型数据库的核心,并且他们是包含关系,即表由列组成,而数据库是表的集合。
MetaData
MetaData是 Table 对象的集合,他是数据库的映射。因此对表的相关操作都是绑定在 MetaData 对象之上的,其中包括创建表、删除表这两个核心操作:
Python
MetaData(
schema:str=None, # 定义默认的 schema,默认由 Table 自己指定
info:dict=None, # 填充 SchemaItem.info 属性
)
他提供了几个方法用于处理绑定到 MetaData 中的表:
create_all(bind:Engine|Connection, tables:list=None, checkfirst=True)
: 创建由 tables 指定的表(必须绑定到该 MetaData 中),如果 checkfirst 为 True 不对已经存在的表执行创建drop_all(bind:Engine|Connection, tables:list=None, checkfirst=True)
: 删除 tables 指定的表(必须绑定到该 MetaData 中),如果 checkfirst 为 True 会在删除前先检查reflect(bind:Engine|Connection, schema:str=None, views:bool=True, only:list=None)
: 反射指定 schema 的由 only 定义的所有表,如果 views 为 True 同时反射视图
他还提供了一个有用的属性 MetaData.tables
来返回绑定到该 MetaData 中的表对象,这在反射后查看表信息很有用。他返回的是 FacadeDict
对象,本质上是 dict 的封装,其中表名为键,表对象为值:
Python
from sqlachemy import create_engine, MetaData
engine = create_engine(url)
metadata = MetaData()
# 反射,结果会保存到 metadata 对象中
metadata.reflect(engine, schema='cnopendata')
# 返回的就是一个类 dict 对象
metadata.tables['student']
Table('student', MetaData(), Column('id', VARCHAR(length=5), table=<student>, primary_key=True, nullable=False), Column('name', VARCHAR(length=20), table=<student>, nullable=False), Column('dept_name', VARCHAR(length=20), ForeignKey('department.dept_name'), table=<student>), Column('tot_cred', NUMERIC(precision=3, scale=0), table=<student>), schema=None)
Table
Table表示数据库中的表:
Python
Table(
name:str, # 表名,注意是区分大小写的即构建 SQL 时会发送引号
metadata:MetaData, # 要绑定到的 MetaData 对象即位于的数据库中
*Columns, # 定义列,如果定义了 autoload_with 则可以不定义
schema:str=None, # 指定表的 schema,如果为 None 使用 MetaData 中的指定
comment:str=None, # 表注释
autoload_with:Engine=None, # 用于反射的 engine 或 Connection
... # 表级别约束
)
Table 上绑定了一个 Table.columns/Table.c
属性来遍历其中的列:
Python
student = metadata.tables['student']
student.columns
# <sqlalchemy.sql.base.ReadOnlyColumnCollection at 0x7f81a4ad2f20>
student.columns.id
Column('id', VARCHAR(length=5), table=<student>, primary_key=True, nullable=False)
Table 上绑定的方法分为三种类别:
- 构造 Table 的方法,例如像 Table 中添加 Columns、添加依赖等。这些通常应该在调用 Table 时构建好,相当于后悔药
- 构建基于 Table 的 SQL 语句,他是构建SQL Statements and Expression Language的基础,例如
Table.select()
这样的方法 - 还有就是对表的创建、删除等,这个是 schema 应该管理的内容
-
create(bind:Engine|Connection, checkfirst=False)
: 创建表 -drop(bind:Engine|Connection, checkfirst=False)
: 删除表
Tips
Table 上的创建和删除默认 checkfirst 都是 False,即无论是否表存在都会发送 CREATE 或 DROP 语句,这也是与 MetaData 上不一样的一点。
Column
Column 表示表中的列: