SqlAlchemy-2-0-中文文档-二十二-
SqlAlchemy 2.0 中文文档(二十二)
反射数据库对象
可以命令Table
对象从数据库中已经存在的相应数据库架构对象中加载关于自身的信息。这个过程称为反射。在最简单的情况下,您只需要指定表名、一个MetaData
对象和autoload_with
参数:
>>> messages = Table("messages", metadata_obj, autoload_with=engine)
>>> [c.name for c in messages.columns]
['message_id', 'message_name', 'date']
上述操作将使用给定的引擎来查询有关messages
表格的数据库信息,然后将生成Column
、ForeignKey
和其他对象,这些对象对应于此信息,就像Table
对象在 Python 中手工构造一样。
当表格被反射时,如果给定的表格通过外键引用另一个表格,那么在表示连接的MetaData
对象中将创建第二个 Table
对象。下面假设表格shopping_cart_items
引用了一个名为shopping_carts
的表格。反射shopping_cart_items
表格的效果是shopping_carts
表格也将被加载:
>>> shopping_cart_items = Table("shopping_cart_items", metadata_obj, autoload_with=engine)
>>> "shopping_carts" in metadata_obj.tables
True
MetaData
具有一种有趣的“类单例”行为,即如果您单独请求了两个表格,MetaData
将确保为每个不同的表名创建一个 Table
对象。如果具有给定名称的表格已经存在,则Table
构造函数实际上会将已经存在的Table
对象返回给您。例如,我们可以通过以下方式访问已经生成的shopping_carts
表格:
shopping_carts = Table("shopping_carts", metadata_obj)
当然,无论如何,最好在上述表格中使用autoload_with=engine
。这样,如果尚未加载表格的属性,它们将被加载。只有在尚未加载表格的情况下才会自动加载表格;一旦加载,对于具有相同名称的新调用Table
将不会重新发出任何反射查询。
覆盖反射的列
当反映表格时,可以通过显式值覆盖单个列;这对于指定自定义数据类型、数据库中可能未配置的主键等约束非常方便:
>>> mytable = Table(
... "mytable",
... metadata_obj,
... Column(
... "id", Integer, primary_key=True
... ), # override reflected 'id' to have primary key
... Column("mydata", Unicode(50)), # override reflected 'mydata' to be Unicode
... # additional Column objects which require no change are reflected normally
... autoload_with=some_engine,
... )
另请参阅
使用自定义类型和反射 - 说明了上述列覆盖技术如何应用于使用自定义数据类型进行表反射。
反射视图
反射系统也可以反射视图。基本用法与表的用法相同:
my_view = Table("some_view", metadata, autoload_with=engine)
在上面,my_view
是一个具有 Column
对象的 Table
对象,表示视图“some_view”中每列的名称和类型。
通常,在反映视图时,至少希望有一个主键约束,如果可能的话,也有外键。视图反射不会推断这些约束。
使用“覆盖”技术,明确指定那些是主键的列或具有外键约束的列:
my_view = Table(
"some_view",
metadata,
Column("view_id", Integer, primary_key=True),
Column("related_thing", Integer, ForeignKey("othertable.thing_id")),
autoload_with=engine,
)
一次性反射所有表格
MetaData
对象还可以获取表的列表并反映全部。这通过使用 reflect()
方法实现。调用后,所有定位的表格都存在于 MetaData
对象的表字典中:
metadata_obj = MetaData()
metadata_obj.reflect(bind=someengine)
users_table = metadata_obj.tables["users"]
addresses_table = metadata_obj.tables["addresses"]
metadata.reflect()
还提供了一种方便的方式来清除或删除数据库中的所有行:
metadata_obj = MetaData()
metadata_obj.reflect(bind=someengine)
with someengine.begin() as conn:
for table in reversed(metadata_obj.sorted_tables):
conn.execute(table.delete())
从其他架构中反射表格
章节 指定架构名称 介绍了表架构的概念,这是数据库中包含表和其他对象的命名空间,可以明确指定。Table
对象的“架构”,以及视图、索引和序列等其他对象的“架构”,可以使用 Table.schema
参数进行设置,也可以使用 MetaData.schema
参数作为 MetaData
对象的默认架构。
此架构参数的使用直接影响表反射功能在被要求反射对象时的搜索位置。例如,给定通过其 MetaData.schema
参数配置了默认架构名称“project”的 MetaData
对象:
>>> metadata_obj = MetaData(schema="project")
然后,MetaData.reflect()
将利用配置的.schema
进行反射:
>>> # uses `schema` configured in metadata_obj
>>> metadata_obj.reflect(someengine)
最终结果是,来自“project”模式的Table
对象将被反映出来,并且它们将以该名称作为模式限定进行填充:
>>> metadata_obj.tables["project.messages"]
Table('messages', MetaData(), Column('message_id', INTEGER(), table=<messages>), schema='project')
类似地,包括Table.schema
参数的单个Table
对象也将从该数据库模式反映出来,覆盖可能已经在拥有的MetaData
集合上配置的任何默认模式:
>>> messages = Table("messages", metadata_obj, schema="project", autoload_with=someengine)
>>> messages
Table('messages', MetaData(), Column('message_id', INTEGER(), table=<messages>), schema='project')
最后,MetaData.reflect()
方法本身也允许传递一个MetaData.reflect.schema
参数,因此我们也可以为默认配置的MetaData
对象从“project”模式加载表:
>>> metadata_obj = MetaData()
>>> metadata_obj.reflect(someengine, schema="project")
我们可以使用不同的MetaData.schema
参数(或者完全不使用)任意多次调用MetaData.reflect()
,以继续用更多对象填充MetaData
对象:
>>> # add tables from the "customer" schema
>>> metadata_obj.reflect(someengine, schema="customer")
>>> # add tables from the default schema
>>> metadata_obj.reflect(someengine)
与默认模式交互的模式限定反射
最佳实践总结部分
在本节中,我们讨论了 SQLAlchemy 关于数据库会话中“默认模式”可见的表的反射行为,以及这些如何与明确包含模式的 SQLAlchemy 指令相互作用。作为最佳实践,请确保数据库的“默认”模式只是一个单一名称,而不是名称列表;对于属于此“默认”模式并且可以在 DDL 和 SQL 中不带模式限定命名的表,请将相应的Table.schema
和类似的模式参数设置为它们的默认值None
。
如 在 MetaData 中指定默认模式名称 中所述,具有模式概念的数据库通常还包括“默认”模式的概念。这自然是因为当引用没有模式的表对象时(这是常见的情况),支持模式的数据库仍然会认为该表在某处存在“模式”。一些数据库,如 PostgreSQL,将这个概念进一步扩展为 模式搜索路径,在特定数据库会话中可以考虑多个模式名称为“隐式”;引用其中任何一个模式中的表名都不需要存在模式名称(与此同时,如果模式名称存在,则也是完全可以的)。
由于大多数关系型数据库都有特定的表对象概念,可以以模式限定的方式引用,也可以以“隐式”方式引用,即没有模式存在,这给 SQLAlchemy 的反射特性带来了复杂性。以模式限定方式反射表将始终填充其 Table.schema
属性,并且会影响此 Table
如何组织到 MetaData.tables
集合中,也就是以模式限定方式。相反,以非模式限定方式反射 同样的 表将使其以非模式限定方式组织到 MetaData.tables
集合中。最终的结果是,单个 MetaData
集合中将存在两个独立的表示实际数据库中同一表的 Table
对象。
为了说明这个问题的影响,考虑前面示例中“project”模式中的表,并假设“project”模式也是我们数据库连接的默认模式,或者如果使用 PostgreSQL 等数据库,则假设“project”模式设置在 PostgreSQL 的 search_path
中。这意味着数据库接受以下两个 SQL 语句作为等价:
-- schema qualified
SELECT message_id FROM project.messages
-- non-schema qualified
SELECT message_id FROM messages
在 SQLAlchemy 中,这并不是一个问题,因为可以以两种方式找到表。但是,在 SQLAlchemy 中,是Table
对象的标识决定了它在 SQL 语句中的语义角色。基于 SQLAlchemy 当前的决策,这意味着如果我们以模式限定的方式和非模式限定的方式反射相同的“messages”表,我们将得到两个不会被视为语义等同的Table
对象:
>>> # reflect in non-schema qualified fashion
>>> messages_table_1 = Table("messages", metadata_obj, autoload_with=someengine)
>>> # reflect in schema qualified fashion
>>> messages_table_2 = Table(
... "messages", metadata_obj, schema="project", autoload_with=someengine
... )
>>> # two different objects
>>> messages_table_1 is messages_table_2
False
>>> # stored in two different ways
>>> metadata.tables["messages"] is messages_table_1
True
>>> metadata.tables["project.messages"] is messages_table_2
True
当被反映的表包含对其他表的外键引用时,上述问题变得更加复杂。假设“messages”有一个“project_id”列,它引用另一个模式本地表“projects”的行,这意味着“messages”表的定义中有一个ForeignKeyConstraint
对象。
我们可能会发现自己处于一个情况下,其中一个MetaData
集合可能包含表示这两个数据库表的四个Table
对象,其中一个或两个附加表是由反射过程生成的;这是因为当反射过程遇到要反射的表上的外键约束时,它会分支出去反射该引用表。它用于为这个引用表分配模式的决策是,如果拥有的Table
也省略了其模式名称,并且这两个对象位于相同的模式中,则 SQLAlchemy 将省略默认模式从反射的ForeignKeyConstraint
对象中,但如果没有省略,则包括它。
常见的情况是以模式限定的方式反射表,然后以模式限定的方式加载一个相关表:
>>> # reflect "messages" in a schema qualified fashion
>>> messages_table_1 = Table(
... "messages", metadata_obj, schema="project", autoload_with=someengine
... )
上述messages_table_1
也将以模式限定的方式引用projects
。这个projects
表将自动反映出“messages”引用它的事实:
>>> messages_table_1.c.project_id
Column('project_id', INTEGER(), ForeignKey('project.projects.project_id'), table=<messages>)
如果代码的其他部分以非模式限定的方式反映“projects”,那么现在有两个不同的项目表:
>>> # reflect "projects" in a non-schema qualified fashion
>>> projects_table_1 = Table("projects", metadata_obj, autoload_with=someengine)
>>> # messages does not refer to projects_table_1 above
>>> messages_table_1.c.project_id.references(projects_table_1.c.project_id)
False
>>> # it refers to this one
>>> projects_table_2 = metadata_obj.tables["project.projects"]
>>> messages_table_1.c.project_id.references(projects_table_2.c.project_id)
True
>>> # they're different, as one non-schema qualified and the other one is
>>> projects_table_1 is projects_table_2
False
上述混淆可能会在使用表反射加载应用程序级Table
对象的应用程序中以及在迁移场景中(尤其是使用 Alembic Migrations 检测新表和外键约束时)引起问题。
以上行为可以通过坚持一项简单的做法来纠正:
- 对于期望位于数据库默认模式中的任何
Table
,不要包含Table.schema
参数。
对于支持模式“搜索”路径的 PostgreSQL 和其他数据库,添加以下额外做法:
- 将“搜索路径”限定为仅一个模式,即默认模式。
另请参阅
远程模式表反射和 PostgreSQL 搜索路径 - 关于 PostgreSQL 数据库的此行为的附加细节。## 使用检查器进行精细化反射
还提供了一个低级接口,它提供了一种与后端无关的从给定数据库加载模式、表、列和约束描述列表的系统。这被称为“检查器”:
from sqlalchemy import create_engine
from sqlalchemy import inspect
engine = create_engine("...")
insp = inspect(engine)
print(insp.get_table_names())
对象名称 | 描述 |
---|---|
Inspector | 执行数据库模式检查。 |
ReflectedCheckConstraint | 表示与CheckConstraint 对应的反射元素的字典。 |
ReflectedColumn | 表示与Column 对象对应的反射元素的字典。 |
ReflectedComputed | 表示计算列的反射元素,对应于Computed 构造。 |
ReflectedForeignKeyConstraint | 表示与ForeignKeyConstraint 对应的反射元素的字典。 |
ReflectedIdentity | 表示列的反射 IDENTITY 结构,对应于Identity 构造。 |
ReflectedIndex | 表示与Index 对应的反射元素的字典。 |
ReflectedPrimaryKeyConstraint | 表示与PrimaryKeyConstraint 对应的反射元素的字典。 |
ReflectedTableComment | 表示对应于Table.comment 属性的反射注释的字典。 |
ReflectedUniqueConstraint | 表示对应于UniqueConstraint 的反射元素的字典。 |
class sqlalchemy.engine.reflection.Inspector
执行数据库模式检查。
Inspector 充当Dialect
的反射方法的代理,提供一致的接口以及对先前获取的元数据的缓存支持。
Inspector
对象通常通过inspect()
函数创建,该函数可以传递一个Engine
或一个Connection
:
from sqlalchemy import inspect, create_engine
engine = create_engine('...')
insp = inspect(engine)
在上述情况中,与引擎关联的Dialect
可能选择返回一个提供了特定于方言目标数据库的额外方法的Inspector
子类。
成员
init(), bind, clear_cache(), default_schema_name, dialect, engine, from_engine(), get_check_constraints(), get_columns(), get_foreign_keys(), get_indexes(), get_materialized_view_names(), get_multi_check_constraints(), get_multi_columns(), get_multi_foreign_keys(), get_multi_indexes(), get_multi_pk_constraint(), get_multi_table_comment(), get_multi_table_options(), get_multi_unique_constraints(), get_pk_constraint(), get_schema_names(), get_sequence_names(), get_sorted_table_and_fkc_names(), get_table_comment(), get_table_names(), get_table_options(), get_temp_table_names(), get_temp_view_names(), get_unique_constraints(), get_view_definition(), get_view_names(), has_index(), has_schema(), has_sequence(), has_table(), info_cache, reflect_table(), sort_tables_on_foreign_key_dependency()
类签名
类sqlalchemy.engine.reflection.Inspector
(sqlalchemy.inspection.Inspectable
)
method __init__(bind: Engine | Connection)
初始化一个新的Inspector
。
自版本 1.4 起已弃用:Inspector
上的 init()方法已弃用,并将在将来的版本中删除。请使用Engine
或Connection
上的inspect()
函数来获取Inspector
。
参数:
bind – 一个Connection
,通常是Engine
或Connection
的实例。
对于Inspector
的方言特定实例,请参阅Inspector.from_engine()
。
attribute bind: Engine | Connection
method clear_cache() → None
重置此Inspector
的缓存。
具有数据缓存的检查方法在下次调用以获取新数据时将发出 SQL 查询。
版本 2.0 中的新功能。
attribute default_schema_name
返回当前引擎数据库用户的方言呈现的默认模式名称。
例如,对于 PostgreSQL 通常为public
,对于 SQL Server 为dbo
。
attribute dialect: Dialect
attribute engine: Engine
classmethod from_engine(bind: Engine) → Inspector
从给定的引擎或连接构造一个新的特定于方言的 Inspector 对象。
自版本 1.4 起已弃用:Inspector
上的 from_engine()方法已弃用,并将在将来的版本中删除。请使用Engine
或Connection
上的inspect()
函数来获取Inspector
。
参数:
bind – 一个Connection
或Engine
。
该方法与直接构造函数调用Inspector
不同,因为Dialect
有机会提供特定于方言的Inspector
实例,该实例可能提供其他方法。
请参阅Inspector
的示例。
method get_check_constraints(table_name: str, schema: str | None = None, **kw: Any) → List[ReflectedCheckConstraint]
返回table_name
中关于检查约束的信息。
给定一个字符串table_name
和一个可选的字符串模式,将检查约束信息作为ReflectedCheckConstraint
的列表返回。
参数:
-
table_name
– 表的名称字符串。对于特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
**kw
– 传递给特定方言实现的其他关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典列表,每个字典代表检查约束的定义。
另见
Inspector.get_multi_check_constraints()
method get_columns(table_name: str, schema: str | None = None, **kw: Any) → List[ReflectedColumn]
返回table_name
中关于列的信息。
给定一个字符串table_name
和一个可选的字符串schema
,返回列信息作为ReflectedColumn
的列表。
参数:
-
table_name
– 表的名称字符串。对于特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
**kw
– 传递给特定方言实现的其他关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典列表,每个字典代表数据库列的定义。
另见
Inspector.get_multi_columns()
.
method get_foreign_keys(table_name: str, schema: str | None = None, **kw: Any) → List[ReflectedForeignKeyConstraint]
返回table_name
中的外键信息。
给定一个字符串table_name
和一个可选的字符串模式,返回外键信息作为ReflectedForeignKeyConstraint
的列表。
参数:
-
table_name
– 表的字符串名称。对于特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典列表,每个代表一个外键定义。
另请参阅
Inspector.get_multi_foreign_keys()
method get_indexes(table_name: str, schema: str | None = None, **kw: Any) → List[ReflectedIndex]
返回表table_name
中索引的信息。
给定一个字符串table_name
和一个可选的字符串模式,返回索引信息作为ReflectedIndex
的列表。
参数:
-
table_name
– 表的字符串名称。对于特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典列表,每个代表一个索引的定义。
另请参阅
Inspector.get_multi_indexes()
method get_materialized_view_names(schema: str | None = None, **kw: Any) → List[str]
返回模式中所有物化视图的名称。
参数:
-
schema
– 可选,从非默认模式中检索名称。对于特殊引用,请���用quoted_name
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
2.0 版本中的新功能。
另请参阅
Inspector.get_view_names()
method get_multi_check_constraints(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, List[ReflectedCheckConstraint]]
返回给定模式中所有表中检查约束的信息。
可通过将要用于filter_names
的名称传递来过滤表。
对于每个表,值是一个ReflectedCheckConstraint
列表。
参数:
-
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。要进行特殊引用,请使用quoted_name
。 -
filter_names
– 可选择性地仅返回列出的对象的信息。 -
kind
– 指定要反映的对象类型的ObjectKind
。默认为ObjectKind.TABLE
。 -
scope
– 指定要反映默认、临时或任何表的约束的ObjectScope
。默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,其中键是两元组模式、表名,值是字典列表,每个字典表示检查约束的定义。如果未提供模式,则模式为None
。
新版本 2.0 中新增。
另请参见
Inspector.get_check_constraints()
method get_multi_columns(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, List[ReflectedColumn]]
返回给定模式中所有对象中列的信息。
可通过将要使用的名称传递给filter_names
来过滤对象。
对于每个表,值是一个ReflectedColumn
列表。
参数:
-
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。要进行特殊引用,请使用quoted_name
。 -
filter_names
– 可选择性地仅返回列出的对象的信息。 -
kind
– 指定要反映的对象类型的ObjectKind
。默认为ObjectKind.TABLE
。 -
scope
– 指定要反映默认、临时或任何表的列的ObjectScope
。默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,其中键是两元组模式、表名,值是字典列表,每个字典表示数据库列的定义。如果未提供模式,则模式为None
。
新版本 2.0 中新增。
另请参见
Inspector.get_columns()
method get_multi_foreign_keys(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, List[ReflectedForeignKeyConstraint]]
返回给定模式中所有表中外键的信息。
可通过将要使用的名称传递给filter_names
来过滤表。
对于每个表,该值是一个 ReflectedForeignKeyConstraint
列表。
参数:
-
schema
– 字符串模式名称;如果省略,将使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
filter_names
– 可选择仅返回此处列出的对象信息。 -
kind
– 一个指定要反映的对象类型的ObjectKind
。默认为ObjectKind.TABLE
。 -
scope
– 一个指定是否应反映默认、临时或任何表的外键的ObjectScope
。默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给特定方言实现的其他关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,其中键是两元组模式、表名,值是字典列表,每个表示外键定义。如果未提供模式,则模式为 None
。
2.0 版中的新功能。
另请参阅
Inspector.get_foreign_keys()
method get_multi_indexes(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, List[ReflectedIndex]]
返回给定模式中所有对象中索引的信息。
通过将要使用的名称传递给 filter_names
来过滤对象。
对于每个表,该值是一个 ReflectedIndex
列表。
参数:
-
schema
– 字符串模式名称;如果省略,将使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
filter_names
– 可选择仅返回此处列出的对象信息。 -
kind
– 一个指定要反映的对象类型的ObjectKind
。默认为ObjectKind.TABLE
。 -
scope
– 一个指定是否应反映默认、临时或任何表的索引的ObjectScope
。默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给特定方言实现的其他关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,其中键是两元组模式、表名,值是字典列表,每个表示索引的定义。如果未提供模式,则模式为 None
。
2.0 版中的新功能。
另请参阅
Inspector.get_indexes()
method get_multi_pk_constraint(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, ReflectedPrimaryKeyConstraint]
返回给定模式中所有表的主键约束的信息。
通过将要使用的名称传递给 filter_names
来过滤表格。
对于每个表,该值为 ReflectedPrimaryKeyConstraint
。
参数:
-
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。要进行特殊引用,请使用quoted_name
。 -
filter_names
– 可选择仅返回此处列出的对象的信息。 -
kind
– 一个指定要反映的对象类型的ObjectKind
。默认为ObjectKind.TABLE
。 -
scope
– 一个指定应反映默认、临时或任何表的主键的ObjectScope
。默认为ObjectScope.DEFAULT
。 -
**kw
– 要传递给特定方言实现的其他关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,其键为二元组模式、表名,值为每个表示主键约束的定义的字典。如果未提供模式,则模式为 None
。
2.0 版中的新内容。
另请参见
Inspector.get_pk_constraint()
method get_multi_table_comment(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, ReflectedTableComment]
返回给定模式中所有对象中表注释的信息。
可通过传递用于 filter_names
的名称来过滤对象。
对于每个表,该值为 ReflectedTableComment
。
对不支持注释的方言引发 NotImplementedError
。
参数:
-
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。要进行特殊引用,请使用quoted_name
。 -
filter_names
– 可选择仅返回此处列出的对象的信息。 -
kind
– 一个指定要反映的对象类型的ObjectKind
。默认为ObjectKind.TABLE
。 -
scope
– 一个指定应反映默认、临时或任何表的注释的ObjectScope
。默认为ObjectScope.DEFAULT
。 -
**kw
– 要传递给特定方言实现的其他关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,其键为二元组模式、表名,值为表示表注释的字典。如果未提供模式,则模式为 None
。
2.0 版中的新内容。
另请参见
Inspector.get_table_comment()
method get_multi_table_options(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, Dict[str, Any]]
返回指定了在给定模式中创建表时指定的选项的字典。
可通过传递用于 filter_names
的名称来过滤表。
目前包括适用于 MySQL 和 Oracle 表的一些选项。
参数:
-
schema
– 字符串模式名称;如果省略,使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
filter_names
– 可选择仅返回列出的对象的信息。 -
kind
– 一个ObjectKind
,指定要反映的对象类型。默认为ObjectKind.TABLE
。 -
scope
– 一个ObjectScope
,指定是否应反映默认、临时或任何表的选项。默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,其中键是两元组模式、表名,值是具有表选项的字典。每个字典中返回的键取决于正在使用的方言。每个键都以方言名称为前缀。如果未提供模式,则模式为None
。
版本 2.0 中的新功能。
另请参见
Inspector.get_table_options()
method get_multi_unique_constraints(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, List[ReflectedUniqueConstraint]]
返回给定模式中所有表中唯一约束的信息。
可通过传递要用于filter_names
的名称来过滤表。
对于每个表,值是一个ReflectedUniqueConstraint
列表。
参数:
-
schema
– 字符串模式名称;如果省略,使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
filter_names
– 可选择仅返回列出的对象的信息。 -
kind
– 一个ObjectKind
,指定要反映的对象类型。默认为ObjectKind.TABLE
。 -
scope
– 一个ObjectScope
,指定是否应反映默认、临时或任何表的约束。默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,其中键是两元组模式、表名,值是字典列表,每个表示唯一约束的定义。如果未提供模式,则模式为None
。
版本 2.0 中的新功能。
另请参见
Inspector.get_unique_constraints()
method get_pk_constraint(table_name: str, schema: str | None = None, **kw: Any) → ReflectedPrimaryKeyConstraint
返回有关table_name
中主键约束的信息。
给定字符串 table_name
,和可选的字符串模式,作为 ReflectedPrimaryKeyConstraint
返回主键信息。
参数:
-
table_name
– 表的字符串名称。对于特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
**kw
– 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅使用的方言的文档。
返回:
代表主键约束定义的字典。
另请参阅
Inspector.get_multi_pk_constraint()
method get_schema_names(**kw: Any) → List[str]
返回所有模式名称。
参数:
**kw – 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅使用的方言的文档。
method get_sequence_names(schema: str | None = None, **kw: Any) → List[str]
返回模式中的所有序列名称。
参数:
-
schema
– 可选,从非默认模式检索名称。对于特殊引用,请使用quoted_name
。 -
**kw
– 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅使用的方言的文档。
method get_sorted_table_and_fkc_names(schema: str | None = None, **kw: Any) → List[Tuple[str | None, List[Tuple[str, str | None]]]]
返回特定模式中引用的表和外键约束名称的依赖排序。
这将生成 (tablename, [(tname, fkname), (tname, fkname), ...])
的 2 元组,其中包含按创建顺序分组的表名和未被检测为属于循环的外键约束名称。最后一个元素将是 (None, [(tname, fkname), (tname, fkname), ..])
,其中包含剩余的外键约束名称,这些名称需要根据表之间的依赖关系在事后进行单独的创建步骤。
参数:
-
schema
– 要查询的模式名称,如果不是默认模式。 -
**kw
– 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅使用的方言的文档。
另请参阅
Inspector.get_table_names()
sort_tables_and_constraints()
- 与已给定的 MetaData
类似的方法。
method get_table_comment(table_name: str, schema: str | None = None, **kw: Any) → ReflectedTableComment
返回 table_name
的表注释信息。
给定字符串table_name
和可选字符串schema
,将表注释信息作为ReflectedTableComment
返回。
对于不支持注释的方言,引发NotImplementedError
。
参数:
-
table_name
– 表的字符串名称。对于特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,带有表注释。
自版本 1.2 新增。
另请参阅
Inspector.get_multi_table_comment()
method get_table_names(schema: str | None = None, **kw: Any) → List[str]
返回特定模式内的所有表名。
名称预期仅为实际表,而不是视图。视图使用Inspector.get_view_names()
和/或Inspector.get_materialized_view_names()
方法返回。
参数:
-
schema
– 模式名称。如果schema
为None
,则使用数据库的默认模式,否则搜索命名模式。如果数据库不支持命名模式,则如果未将schema
作为None
传递,则行为未定义。对于特殊引用,请使用quoted_name
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
另请参阅
Inspector.get_sorted_table_and_fkc_names()
MetaData.sorted_tables
method get_table_options(table_name: str, schema: str | None = None, **kw: Any) → Dict[str, Any]
返回给定名称的表创建时指定的选项的字典。
目前包括适用于 MySQL 和 Oracle 表的某些选项。
参数:
-
table_name
– 表的字符串名称。对于特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。要进行特殊引用,请使用quoted_name
。 -
**kw
– 传递给方言特定实现的附加关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个包含表选项的字典。返回的键取决于使用的方言。每个键都以方言名称为前缀。
另请参阅
Inspector.get_multi_table_options()
method get_temp_table_names(**kw: Any) → List[str]
返回当前绑定的临时表名称列表。
大多数方言都不支持此方法;目前只有 Oracle、PostgreSQL 和 SQLite 实现了它。
参数:
**kw – 传递给方言特定实现的附加关键字参数。有关更多信息,请参阅正在使用的方言的文档。
method get_temp_view_names(**kw: Any) → List[str]
返回当前绑定的临时视图名称列表。
大多数方言都不支持此方法;目前只有 PostgreSQL 和 SQLite 实现了它。
参数:
**kw – 传递给方言特定实现的附加关键字参数。有关更多信息,请参阅正在使用的方言的文档。
method get_unique_constraints(table_name: str, schema: str | None = None, **kw: Any) → List[ReflectedUniqueConstraint]
返回table_name
中唯一约束的信息。
给定一个字符串table_name
和一个可选的字符串模式,将唯一约束信息返回为一个ReflectedUniqueConstraint
的列表。
参数:
-
table_name
– 表名称字符串。要进行特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。要进行特殊引用,请使用quoted_name
。 -
**kw
– 传递给方言特定实现的附加关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典列表,每个都代表唯一约束的定义。
另请参阅
Inspector.get_multi_unique_constraints()
method get_view_definition(view_name: str, schema: str | None = None, **kw: Any) → str
返回名为view_name
的普通或物化视图的定义。
参数:
-
view_name
– 视图的名称。 -
schema
– 可选,从非默认模式检索名称。要进行特殊引用,请使用quoted_name
。 -
**kw
– 传递给方言特定实现的附加关键字参数。有关更多信息,请参阅正在使用的方言的文档。
method get_view_names(schema: str | None = None, **kw: Any) → List[str]
返回模式中的所有非材料化视图名称。
参数:
-
schema
– 可选,从非默认模式中检索名称。对于特殊引用,请使用quoted_name
。 -
**kw
– 传递给方言特定实现的其他关键字参数。有关更多信息,请参阅正在使用的方言的文档。
从版本 2.0 开始更改:对于以前在此列表中包括材料化视图名称的方言(当前为 PostgreSQL),此方法不再返回材料化视图的名称。应改为使用 Inspector.get_materialized_view_names()
方法。
另请参阅
Inspector.get_materialized_view_names()
method has_index(table_name: str, index_name: str, schema: str | None = None, **kw: Any) → bool
检查数据库中特定索引名称的存在。
参数:
-
table_name
– 索引所属表的名称 -
index_name
– 要检查的索引名称 -
schema
– 查询的模式名称,如果不是默认模式。 -
**kw
– 传递给方言特定实现的其他关键字参数。有关更多信息,请参阅正在使用的方言的文档。
版本 2.0 中的新功能。
method has_schema(schema_name: str, **kw: Any) → bool
如果后端具有给定名称的模式,则返回 True。
参数:
-
schema_name
– 要检查的模式名称 -
**kw
– 传递给方言特定实现的其他关键字参数。有关更多信息,请参阅正在使用的方言的文档。
版本 2.0 中的新功能。
method has_sequence(sequence_name: str, schema: str | None = None, **kw: Any) → bool
如果后端具有给定名称的序列,则返回 True。
参数:
-
sequence_name
– 要检查的序列名称 -
schema
– 查询的模式名称,如果不是默认模式。 -
**kw
– 传递给方言特定实现的其他关键字参数。有关更多信息,请参阅正在使用的方言的文档。
版本 1.4 中的新功能。
method has_table(table_name: str, schema: str | None = None, **kw: Any) → bool
如果后端具有给定名称的表、视图或临时表,则返回 True。
参数:
-
table_name
– 要检查的表名称 -
schema
– 查询的模式名称,如果不是默认模式。 -
**kw
– 传递给方言特定实现的其他关键字参数。有关更多信息,请参阅正在使用的方言的文档。
从版本 1.4 开始:- Inspector.has_table()
方法替换了 Engine.has_table()
方法。
从版本 2.0 开始更改:Inspector.has_table()
现在正式支持检查额外的类似表的对象:
-
任何类型的视图(普通或材料化)
-
任何类型的临时表
以前,这两个检查没有正式指定,并且不同的方言在行为上会有所不同。方言测试套件现在包括所有这些对象类型的测试,并且应该由所有包含 SQLAlchemy 的方言支持。但是,第三方方言中的支持可能滞后。
attribute info_cache: Dict[Any, Any]
method reflect_table(table: Table, include_columns: Collection[str] | None, exclude_columns: Collection[str] = (), resolve_fks: bool = True, _extend_on: Set[Table] | None = None, _reflect_info: _ReflectionInfo | None = None) → None
给定一个 Table
对象,根据内省加载其内部构造。
这是大多数方言用于生成表反射的底层方法。直接用法如下:
from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy import inspect
engine = create_engine('...')
meta = MetaData()
user_table = Table('user', meta)
insp = inspect(engine)
insp.reflect_table(user_table, None)
从版本 1.4 开始更改:从 reflecttable
更名为 reflect_table
参数:
-
table
– 一个Table
实例。 -
include_columns
– 要包含在反射过程中的字符串列名列表。如果为None
,则反射所有列。
method sort_tables_on_foreign_key_dependency(consider_schemas: Collection[str | None] = (None,), **kw: Any) → List[Tuple[Tuple[str | None, str] | None, List[Tuple[Tuple[str | None, str], str | None]]]]
返回在多个模式中引用的依赖项排序的表和外键约束名称。
此方法可以与 Inspector.get_sorted_table_and_fkc_names()
进行比较,后者一次只能处理一个模式;在这里,该方法是一个通用化的方法,一次可以考虑多个模式,包括解决跨模式外键的问题。
版本 2.0 中新增。
class sqlalchemy.engine.interfaces.ReflectedColumn
表示与 Column
对象对应的反射元素的字典。
ReflectedColumn
结构是由 get_columns
方法返回的。
成员
autoincrement, comment, computed, default, dialect_options, identity, name, nullable, type
类签名
类 sqlalchemy.engine.interfaces.ReflectedColumn
(builtins.dict
)
attribute autoincrement: NotRequired[bool]
数据库相关的自增标志。
此标志指示列是否具有某种数据库端的 “autoincrement” 标志。在 SQLAlchemy 中,其他类型的列也可以充当 “autoincrement” 列,而不一定在它们身上具有这样的标志。
有关 “autoincrement” 的更多背景信息,请参阅 Column.autoincrement
。
attribute comment: NotRequired[str | None]
如果存在,为列添加注释。只有一些方言会返回此键。
attribute computed: NotRequired[ReflectedComputed]
指示此列由数据库计算。只有一些方言会返回此键。
版本 1.3.16 中新增:- 增加对计算反射的支持。
attribute default: str | None
列默认表达式作为 SQL 字符串
attribute dialect_options: NotRequired[Dict[str, Any]]
检测到此反射对象的附加方言特定选项
attribute identity: NotRequired[ReflectedIdentity]
指示此列为 IDENTITY 列。只有一些方言会返回此键。
版本 1.4 中新增:- 增加对标识列反射的支持。
attribute name: str
列名
attribute nullable: bool
如果列为 NULL 或 NOT NULL,则为布尔标志
attribute type: TypeEngine[Any]
列类型表示为TypeEngine
实例。
class sqlalchemy.engine.interfaces.ReflectedComputed
表示计算列的反射元素,对应于Computed
结构。
ReflectedComputed
结构是 ReflectedColumn
结构的一部分,由 Inspector.get_columns()
方法返回。
成员
persisted,sqltext
类签名
类sqlalchemy.engine.interfaces.ReflectedComputed
(builtins.dict
)
attribute persisted: NotRequired[bool]
指示值是存储在表中还是按需计算
attribute sqltext: str
用于生成此列的表达式,返回为字符串 SQL 表达式
class sqlalchemy.engine.interfaces.ReflectedCheckConstraint
字典表示反射元素,对应于CheckConstraint
。
ReflectedCheckConstraint
结构由 Inspector.get_check_constraints()
方法返回。
成员
dialect_options,sqltext
类签名
类sqlalchemy.engine.interfaces.ReflectedCheckConstraint
(builtins.dict
)
attribute dialect_options: NotRequired[Dict[str, Any]]
检测到此检查约束的附加方言特定选项
版本 1.3.8 中新增。
attribute sqltext: str
检查约束的 SQL 表达式
class sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint
字典表示对应于 ForeignKeyConstraint
的反射元素。
ReflectedForeignKeyConstraint
结构是由 Inspector.get_foreign_keys()
方法返回的。
成员
constrained_columns, options, referred_columns, referred_schema, referred_table
类签名
类sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint
(builtins.dict
)
attribute constrained_columns: List[str]
构成外键的本地列名称
attribute options: NotRequired[Dict[str, Any]]
这个外键约束检测到了额外的选项
attribute referred_columns: List[str]
对应于 constrained_columns
的被引用列名称
attribute referred_schema: str | None
被引用表的架构名称
attribute referred_table: str
被引用表的名称
class sqlalchemy.engine.interfaces.ReflectedIdentity
表示列的反射 IDENTITY 结构,对应于 Identity
结构。
ReflectedIdentity
结构是 ReflectedColumn
结构的一部分,由 Inspector.get_columns()
方法返回。
成员
always, cache, cycle, increment, maxvalue, minvalue, nomaxvalue, nominvalue, on_null, order, start
类签名
类sqlalchemy.engine.interfaces.ReflectedIdentity
(builtins.dict
)
attribute always: bool
身份列的类型
attribute cache: int | None
预先计算的序列中的未来值的数量。
attribute cycle: bool
允许序列在达到最大值或最小值时环绕。
attribute increment: int
序列的增量值
attribute maxvalue: int
序列的最大值。
attribute minvalue: int
序列的最小值。
attribute nomaxvalue: bool
没有序列的最大值。
attribute nominvalue: bool
没有序列的最小值。
attribute on_null: bool
表示 ON NULL
attribute order: bool
如果为真,则渲染 ORDER 关键字。
attribute start: int
序列的起始索引
class sqlalchemy.engine.interfaces.ReflectedIndex
表示与Index
对应的反射元素的字典。
ReflectedIndex
结构由 Inspector.get_indexes()
方法返回。
成员
column_names、column_sorting、dialect_options、duplicates_constraint、expressions、include_columns、name、unique
类签名
类sqlalchemy.engine.interfaces.ReflectedIndex
(builtins.dict
)
attribute column_names: List[str | None]
索引引用的列名。如果列表中的元素是表达式,则为None
,并在expressions
列表中返回。
attribute column_sorting: NotRequired[Dict[str, Tuple[str]]]
可选字典,将列名或表达式映射到排序关键字元组,可能包括asc
、desc
、nulls_first
、nulls_last
。
新版本 1.3.5 中的内容。
attribute dialect_options: NotRequired[Dict[str, Any]]
检测到的此索引的附加方言特定选项
attribute duplicates_constraint: NotRequired[str | None]
指示此索引是否反映了具有此名称的约束
attribute expressions: NotRequired[List[str]]
组成索引的表达式。当存在时,此列表包含普通列名(也在column_names
中)和表达式(在column_names
中为None
)。
attribute include_columns: NotRequired[List[str]]
在支持的数据库中包含在 INCLUDE 子句中的列。
自版本 2.0 起已弃用:遗留值,将被替换为index_dict["dialect_options"]["<dialect name>_include"]
attribute name: str | None
索引名称
attribute unique: bool
索引是否具有唯一标志
class sqlalchemy.engine.interfaces.ReflectedPrimaryKeyConstraint
表示与PrimaryKeyConstraint
对应的反射元素的字典。
ReflectedPrimaryKeyConstraint
结构由 Inspector.get_pk_constraint()
方法返回。
成员
constrained_columns, dialect_options
类签名
类 sqlalchemy.engine.interfaces.ReflectedPrimaryKeyConstraint
(builtins.dict
)
attribute constrained_columns: List[str]
组成主键的列名
attribute dialect_options: NotRequired[Dict[str, Any]]
检测到针对此主键的其他方言特定选项
class sqlalchemy.engine.interfaces.ReflectedUniqueConstraint
表示与 UniqueConstraint
对应的反映元素的字典。
ReflectedUniqueConstraint
结构由 Inspector.get_unique_constraints()
方法返回。
成员
column_names, dialect_options, duplicates_index
类签名
类 sqlalchemy.engine.interfaces.ReflectedUniqueConstraint
(builtins.dict
)
attribute column_names: List[str]
组成唯一约束的列名
attribute dialect_options: NotRequired[Dict[str, Any]]
检测到针对此唯一约束的其他方言特定选项
attribute duplicates_index: NotRequired[str | None]
指示此唯一约束是否重复了具有此名称的索引
class sqlalchemy.engine.interfaces.ReflectedTableComment
表示与 Table.comment
属性对应的反映注释的字典。
ReflectedTableComment
结构由 Inspector.get_table_comment()
方法返回。
成员
text
类签名
类 sqlalchemy.engine.interfaces.ReflectedTableComment
(builtins.dict
)
attribute text: str | None
注释的文本 ## 使用与数据库无关的类型反射
当表的列被反映时,可以使用 Table.autoload_with
参数或 Inspector.get_columns()
方法,通过 Table
或 Inspector
,数据类型将尽可能与目标数据库特定。这意味着,如果从 MySQL 数据库反映出一个“integer”数据类型,则该类型将由 sqlalchemy.dialects.mysql.INTEGER
类表示,其中包括 MySQL 特定属性,如“display_width”。或者在 PostgreSQL 上,可能返回 PostgreSQL 特定的数据类型,如 sqlalchemy.dialects.postgresql.INTERVAL
或 sqlalchemy.dialects.postgresql.ENUM
。
反映的一个使用案例是将给定的 Table
转移到不同的供应商数据库。为了适应这种使用情况,有一种技术,可以将这些供应商特定的数据类型即时转换为 SQLAlchemy 后端不可知数据类型的实例,例如上面的类型,如 Integer
、Interval
和 Enum
。这可以通过拦截列反映并使用 DDLEvents.column_reflect()
事件与 TypeEngine.as_generic()
方法来实现。
给定 MySQL 中的一个表(选择 MySQL 是因为 MySQL 有很多特定于供应商的数据类型和选项):
CREATE TABLE IF NOT EXISTS my_table (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
data1 VARCHAR(50) CHARACTER SET latin1,
data2 MEDIUMINT(4),
data3 TINYINT(2)
)
上述表包括仅限于 MySQL 的整数类型 MEDIUMINT
和 TINYINT
,以及一个包含 MySQL 专有 CHARACTER SET
选项的 VARCHAR
。如果我们正常反映这个表,它将生成一个包含那些 MySQL 特定数据类型和选项的 Table
对象。
>>> from sqlalchemy import MetaData, Table, create_engine
>>> mysql_engine = create_engine("mysql+mysqldb://scott:tiger@localhost/test")
>>> metadata_obj = MetaData()
>>> my_mysql_table = Table("my_table", metadata_obj, autoload_with=mysql_engine)
上述示例将上述表模式反映到一个新的 Table
对象中。然后,我们可以出于演示目的,使用 CreateTable
构造打印出特定于 MySQL 的“CREATE TABLE”语句:
>>> from sqlalchemy.schema import CreateTable
>>> print(CreateTable(my_mysql_table).compile(mysql_engine))
CREATE TABLE my_table (
id INTEGER(11) NOT NULL AUTO_INCREMENT,
data1 VARCHAR(50) CHARACTER SET latin1,
data2 MEDIUMINT(4),
data3 TINYINT(2),
PRIMARY KEY (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
在上面的例子中,保留了特定于 MySQL 的数据类型和选项。如果我们想要一个能够干净地转移到另一个数据库供应商的 Table
,并且用 Integer
替换特殊数据类型 sqlalchemy.dialects.mysql.MEDIUMINT
和 sqlalchemy.dialects.mysql.TINYINT
,我们可以选择在此表上“泛型化”数据类型,或以任何我们喜欢的方式进行更改,通过使用 DDLEvents.column_reflect()
事件建立一个处理程序。自定义处理程序将使用 TypeEngine.as_generic()
方法将上述 MySQL 特定类型对象转换为通用类型,方法是通过将传递给事件处理程序的列字典条目中的 "type"
条目替换为泛型。此字典的格式在 Inspector.get_columns()
中描述:
>>> from sqlalchemy import event
>>> metadata_obj = MetaData()
>>> @event.listens_for(metadata_obj, "column_reflect")
... def genericize_datatypes(inspector, tablename, column_dict):
... column_dict["type"] = column_dict["type"].as_generic()
>>> my_generic_table = Table("my_table", metadata_obj, autoload_with=mysql_engine)
现在我们得到了一个新的通用 Table
并使用 Integer
作为那些数据类型。我们现在可以在 PostgreSQL 数据库上发出一个“CREATE TABLE”语句,例如:
>>> pg_engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/test", echo=True)
>>> my_generic_table.create(pg_engine)
CREATE TABLE my_table (
id SERIAL NOT NULL,
data1 VARCHAR(50),
data2 INTEGER,
data3 INTEGER,
PRIMARY KEY (id)
)
还需要注意的是,SQLAlchemy 通常会对其他行为做出合理的猜测,例如,MySQL 的 AUTO_INCREMENT
指令在 PostgreSQL 中最接近地使用 SERIAL
自增数据类型表示。
版本 1.4 新增了 TypeEngine.as_generic()
方法,并进一步改进了 DDLEvents.column_reflect()
事件的使用,以便方便地应用于 MetaData
对象。
反射的局限性
需要注意的是,反射过程仅使用在关系数据库中表示的信息重新创建 Table
元数据。根据定义,这个过程无法恢复数据库中实际未存储的模式方面。反射无法获取的状态包括但不限于:
-
客户端默认值,即使用
Column
的default
关键字定义的 Python 函数或 SQL 表达式(请注意,这与通过反射获得的server_default
是分开的)。 -
列信息,例如可能放入
Column.info
字典中的数据 -
.quote
设置对于Column
或Table
的价值。 -
特定
Sequence
与给定Column
的关联
在许多情况下,关系数据库报告的表元数据格式与 SQLAlchemy 中指定的格式不同。从反射返回的 Table
对象不能始终依赖于生成与原始 Python 定义的 Table
对象相同的 DDL。发生这种情况的地方包括服务器默认值、与列关联的序列以及有关约束和数据类型的各种特殊情况。服务器端默认值可能会带有转换指令(通常 PostgreSQL 将包括一个 ::<type>
转换)或不同于最初指定的引号模式。
另一类限制包括反射仅部分或尚未定义的模式结构。最近对反射的改进允许反映视图、索引和外键选项等内容。截至本文撰写时,像 CHECK 约束、表注释和触发器等结构并未反映。
覆盖反射列
在反射表时,可以使用显式值覆盖单个列;这对于指定自定义数据类型、在数据库中未配置的主键等约束非常方便:
>>> mytable = Table(
... "mytable",
... metadata_obj,
... Column(
... "id", Integer, primary_key=True
... ), # override reflected 'id' to have primary key
... Column("mydata", Unicode(50)), # override reflected 'mydata' to be Unicode
... # additional Column objects which require no change are reflected normally
... autoload_with=some_engine,
... )
另请参阅
使用自定义类型和反射 - 演示了上述列覆盖技术如何应用于使用自定义数据类型进行表反射。
反射视图
反射系统也可以反映视图。基本用法与表相同:
my_view = Table("some_view", metadata, autoload_with=engine)
在上面,my_view
是一个Table
对象,其中包含代表视图“some_view”中每个列的名称和类型的Column
对象。
通常,在反射视图时,至少希望有一个主键约束,如果可能的话还有外键。视图反射不会推断这些约束。
使用“override”技术,明确指定那些是主键或具有外键约束的列:
my_view = Table(
"some_view",
metadata,
Column("view_id", Integer, primary_key=True),
Column("related_thing", Integer, ForeignKey("othertable.thing_id")),
autoload_with=engine,
)
一次性反射所有表
MetaData
对象还可以获取表列表并反射完整集合。通过使用reflect()
方法实现。调用后,所有定位的表都存在于MetaData
对象的表字典中:
metadata_obj = MetaData()
metadata_obj.reflect(bind=someengine)
users_table = metadata_obj.tables["users"]
addresses_table = metadata_obj.tables["addresses"]
metadata.reflect()
还提供了一种方便的方法来清除或删除数据库中的所有行:
metadata_obj = MetaData()
metadata_obj.reflect(bind=someengine)
with someengine.begin() as conn:
for table in reversed(metadata_obj.sorted_tables):
conn.execute(table.delete())
从其他模式反射表
章节指定模式名称介绍了表模式的概念,这是数据库中包含表和其他对象的命名空间,并且可以明确指定。可以使用Table.schema
参数为Table
对象以及其他对象如视图、索引和序列设置“模式”,还可以使用MetaData.schema
参数为MetaData
对象设置默认模式。
此模式参数的使用直接影响表反射功能在被要求反射对象时查找的位置。例如,给定一个通过其MetaData.schema
参数配置了默认模式名称“project”的MetaData
对象:
>>> metadata_obj = MetaData(schema="project")
MetaData.reflect()
然后将利用配置的.schema
进行反射:
>>> # uses `schema` configured in metadata_obj
>>> metadata_obj.reflect(someengine)
最终结果是,“project”模式中的Table
对象将被反射,并且它们将以该名称的模式限定形式填充:
>>> metadata_obj.tables["project.messages"]
Table('messages', MetaData(), Column('message_id', INTEGER(), table=<messages>), schema='project')
同样,如果 Table
对象中包含了 Table.schema
参数,那么该表也将从该数据库模式中反映出来,覆盖了可能已在拥有的 MetaData
集合上配置的任何默认模式:
>>> messages = Table("messages", metadata_obj, schema="project", autoload_with=someengine)
>>> messages
Table('messages', MetaData(), Column('message_id', INTEGER(), table=<messages>), schema='project')
最后,MetaData.reflect()
方法本身也允许传递一个 MetaData.reflect.schema
参数,因此我们也可以为默认配置的 MetaData
对象从“project”模式加载表:
>>> metadata_obj = MetaData()
>>> metadata_obj.reflect(someengine, schema="project")
我们可以使用不同的 MetaData.schema
参数(或者不使用任何参数)多次调用 MetaData.reflect()
方法,以便继续向 MetaData
对象中添加更多对象:
>>> # add tables from the "customer" schema
>>> metadata_obj.reflect(someengine, schema="customer")
>>> # add tables from the default schema
>>> metadata_obj.reflect(someengine)
带有默认模式的模式限定反射的交互
最佳实践总结部分
在本节中,我们讨论了 SQLAlchemy 关于数据库会话中“默认模式”中可见表的反射行为,以及这些与显式包含模式的 SQLAlchemy 指令的交互方式。 作为最佳实践,请确保数据库的“默认”模式只是一个单一名称,而不是名称列表; 对于属于此“默认”模式并且可以在 DDL 和 SQL 中无需模式限定名称的表,将相应的 Table.schema
和类似的模式参数设置为其默认值 None
。
如 使用 MetaData 指定默认模式名称 中所述,具有模式概念的数据库通常也包括“默认”模式的概念。 这自然是因为,当一个通常的表对象没有模式时,具有模式的数据库仍然会认为该表在某处的“模式”中。 一些数据库(如 PostgreSQL)进一步将此概念扩展为“模式搜索路径”的概念,其中可以在特定数据库会话中将 多个 模式名称视为“隐式”; 指的是任何这些模式中的表名称将不需要模式名称存在(同时,如果模式名称存在,也是完全可以的)。
由于大多数关系数据库都有一个特定的表对象的概念,可以以模式限定的方式引用它,以及一个“隐式”的方式,其中没有模式存在,这为 SQLAlchemy 的反射特性带来了复杂性。以模式限定的方式反映表将始终填充其Table.schema
属性,并且还会影响如何将此Table
组织到MetaData.tables
集合中,即以模式限定的方式。相反,以非模式限定的方式反映相同的表将在不模式限定的情况下将其组织到MetaData.tables
集合中。最终的结果是,在实际数据库中,单一的MetaData
集合中会有两个单独的Table
对象,表示相同的表。
为了说明这个问题的影响,考虑上一个示例中来自“project”模式的表,并假设“project”模式是我们数据库连接的默认模式,或者如果使用诸如 PostgreSQL 之类的数据库,则假设“project”模式在 PostgreSQL 中设置了search_path
。这意味着数据库接受以下两个 SQL 语句是等价的:
-- schema qualified
SELECT message_id FROM project.messages
-- non-schema qualified
SELECT message_id FROM messages
这不是一个问题,因为可以双向找到表。但是在 SQLAlchemy 中,是Table
对象的标识决定了它在 SQL 语句中的语义角色。根据 SQLAlchemy 当前的决定,这意味着如果我们以模式限定和非模式限定的方式同时反映同一个“messages”表,我们会得到两个Table
对象,它们不会被视为语义上等价:
>>> # reflect in non-schema qualified fashion
>>> messages_table_1 = Table("messages", metadata_obj, autoload_with=someengine)
>>> # reflect in schema qualified fashion
>>> messages_table_2 = Table(
... "messages", metadata_obj, schema="project", autoload_with=someengine
... )
>>> # two different objects
>>> messages_table_1 is messages_table_2
False
>>> # stored in two different ways
>>> metadata.tables["messages"] is messages_table_1
True
>>> metadata.tables["project.messages"] is messages_table_2
True
上述问题在反映的表包含对其他表的外键引用时变得更加复杂。假设“messages”有一个“project_id”列,它引用另一个模式本地表“projects”的行,这意味着“messages”表定义的一部分是一个ForeignKeyConstraint
对象。
我们可能会发现自己处于这样一种情况:一个MetaData
集合可能包含多达四个Table
对象,代表这两个数据库表,其中一个或两个附加表是由反射过程生成的;这是因为当反射过程遇到一个正在被反射的表上的外键约束时,它会分支出去反射那个被引用的表。它用于为这个被引用的表分配模式的决策是,如果拥有的Table
也省略了其模式名称,并且这两个对象位于同一模式中,那么 SQLAlchemy 将省略默认模式的反射ForeignKeyConstraint
对象,但如果没有省略,则包括它。
常见情况是以模式合格的方式反映表,然后以同样的方式加载相关表:
>>> # reflect "messages" in a schema qualified fashion
>>> messages_table_1 = Table(
... "messages", metadata_obj, schema="project", autoload_with=someengine
... )
上述的 messages_table_1
也会以模式合格的方式引用 projects
。这个 projects
表会自动反射,因为 “messages” 引用了它:
>>> messages_table_1.c.project_id
Column('project_id', INTEGER(), ForeignKey('project.projects.project_id'), table=<messages>)
如果代码的其他部分以非模式合格的方式反映“projects”,现在就有了两个不同的 projects 表:
>>> # reflect "projects" in a non-schema qualified fashion
>>> projects_table_1 = Table("projects", metadata_obj, autoload_with=someengine)
>>> # messages does not refer to projects_table_1 above
>>> messages_table_1.c.project_id.references(projects_table_1.c.project_id)
False
>>> # it refers to this one
>>> projects_table_2 = metadata_obj.tables["project.projects"]
>>> messages_table_1.c.project_id.references(projects_table_2.c.project_id)
True
>>> # they're different, as one non-schema qualified and the other one is
>>> projects_table_1 is projects_table_2
False
上述混淆可能会在使用表反射加载应用程序级别Table
对象的应用程序中造成问题,以及在迁移场景中,特别是在使用 Alembic 迁移检测新表和外键约束时。
可以通过坚持一个简单的做法来纠正上述行为:
- 对于任何期望位于数据库的默认模式中的
Table
,不要包含Table.schema
参数。
对于支持模式的“搜索”路径的 PostgreSQL 和其他数据库,请添加以下附加做法:
- 将“搜索路径”限制为一个模式,即默认模式。
另请参阅
远程模式表反射和 PostgreSQL search_path - 关于 PostgreSQL 数据库的此行为的附加详细信息。### 模式合格反射与默认模式的交互
最佳实践概述部分
在本节中,我们将讨论 SQLAlchemy 在数据库会话的“默认模式”中可见的表的反射行为,以及这些表如何与显式包含模式的 SQLAlchemy 指令进行交互。作为最佳实践,请确保数据库的“默认”模式只是一个单一的名称,而不是名称列表;对于属于此“默认”模式且可以在 DDL 和 SQL 中不带模式限定命名的表,将相应的 Table.schema
和类似的模式参数设置为它们的默认值 None
。
如在使用 MetaData 指定默认模式名称中描述的那样,具有模式概念的数据库通常还包括“默认”模式的概念。这自然是因为当人们引用常见的无模式表对象时,具有模式功能的数据库仍会认为该表位于某个“模式”中。一些数据库,如 PostgreSQL,将这个概念进一步发展成为模式搜索路径的概念,其中一个特定数据库会话中可以考虑多个模式名称为“隐式”;引用任何这些模式中的表名都不需要模式名(同时如果模式名存在也完全可以)。
因此,由于大多数关系数据库都有一种特定的表对象的概念,既可以以模式限定的方式引用,也可以以“隐式”方式引用,其中不需要模式,这给 SQLAlchemy 的反射特性带来了复杂性。以模式限定的方式反映表将始终填充其 Table.schema
属性,并且另外影响到这个 Table
如何以模式限定的方式组织到 MetaData.tables
集合中。相反,以非模式限定的方式反映相同的表将以不带模式的方式组织到 MetaData.tables
集合中。最终结果是,在实际数据库中表示同一张表的单个 MetaData
集合中将有两个单独的 Table
对象。
为了说明这个问题的后果,考虑前面示例中“project”模式中的表,并假设“project”模式是我们数据库连接的默认模式,或者如果使用像 PostgreSQL 这样的数据库,假设“project”模式设置在 PostgreSQL 的search_path
中。这意味着数据库接受以下两个 SQL 语句作为等价:
-- schema qualified
SELECT message_id FROM project.messages
-- non-schema qualified
SELECT message_id FROM messages
这并不是一个问题,因为表可以以两种方式找到。然而,在 SQLAlchemy 中,是Table
对象的标识决定了它在 SQL 语句中的语义角色。根据 SQLAlchemy 当前的决策,这意味着如果我们以模式限定和非模式限定的方式反射相同的“messages”表,我们会得到两个不会被视为语义等价的Table
对象:
>>> # reflect in non-schema qualified fashion
>>> messages_table_1 = Table("messages", metadata_obj, autoload_with=someengine)
>>> # reflect in schema qualified fashion
>>> messages_table_2 = Table(
... "messages", metadata_obj, schema="project", autoload_with=someengine
... )
>>> # two different objects
>>> messages_table_1 is messages_table_2
False
>>> # stored in two different ways
>>> metadata.tables["messages"] is messages_table_1
True
>>> metadata.tables["project.messages"] is messages_table_2
True
当被反射的表包含对其他表的外键引用时,上述问题变得更加复杂。假设“messages”有一个“project_id”列,它引用另一个模式本地表“projects”,这意味着“messages”表的定义中包含一个ForeignKeyConstraint
对象。
我们可能会发现自己处于这样一种情况,一个MetaData
集合可能包含代表这两个数据库表的四个Table
对象,其中一个或两个额外的表是由反射过程生成的;这是因为当反射过程遇到被反射表上的外键约束时,它会分支出去反射该引用表。它用于为这个引用表分配模式的决策是,如果拥有的Table
也省略了它的模式名称,那么 SQLAlchemy 将省略默认模式从反射的ForeignKeyConstraint
对象中,如果这两个对象在同一个模式中,则包括它,但如果没有被省略的话。
常见情况是以模式限定方式反射表,然后以模式限定方式加载相关表:
>>> # reflect "messages" in a schema qualified fashion
>>> messages_table_1 = Table(
... "messages", metadata_obj, schema="project", autoload_with=someengine
... )
上述messages_table_1
也将以模式限定方式引用projects
。这个projects
表将被自动反射,因为“messages”引用了它:
>>> messages_table_1.c.project_id
Column('project_id', INTEGER(), ForeignKey('project.projects.project_id'), table=<messages>)
如果代码的其他部分以非模式限定方式反射“projects”,那么现在有两个不同的 projects 表:
>>> # reflect "projects" in a non-schema qualified fashion
>>> projects_table_1 = Table("projects", metadata_obj, autoload_with=someengine)
>>> # messages does not refer to projects_table_1 above
>>> messages_table_1.c.project_id.references(projects_table_1.c.project_id)
False
>>> # it refers to this one
>>> projects_table_2 = metadata_obj.tables["project.projects"]
>>> messages_table_1.c.project_id.references(projects_table_2.c.project_id)
True
>>> # they're different, as one non-schema qualified and the other one is
>>> projects_table_1 is projects_table_2
False
上述混淆可能会在使用表反射加载应用级别Table
对象的应用程序内以及在迁移方案中引起问题,特别是在使用 Alembic Migrations 检测新表和外键约束时。
以上行为可以通过坚持一个简单的做法来纠正:
- 不要为任何期望位于数据库默认模式中的
Table
包括Table.schema
参数。
对于支持“搜索”模式的 PostgreSQL 和其他数据库,添加以下额外的做法:
- 将“搜索路径”限制为仅一个模式,即默认模式。
另请参阅
远程模式表内省和 PostgreSQL search_path - 关于 PostgreSQL 数据库的此行为的附加细节。
使用检查员进行细粒度反射
也提供了低级接口,它提供了一个与后端无关的系统,用于从给定数据库加载模式、表、列和约束描述的列表。这被称为“检查员”:
from sqlalchemy import create_engine
from sqlalchemy import inspect
engine = create_engine("...")
insp = inspect(engine)
print(insp.get_table_names())
对象名称 | 描述 |
---|---|
检查员 | 执行数据库模式检查。 |
ReflectedCheckConstraint | 表示反射元素的字典,对应于CheckConstraint 。 |
ReflectedColumn | 表示反射元素的字典,对应于Column 对象。 |
ReflectedComputed | 表示计算列的反射元素,对应于Computed 构造。 |
ReflectedForeignKeyConstraint | 表示反射元素的字典,对应于ForeignKeyConstraint 。 |
ReflectedIdentity | 表示列的反射身份结构,对应于Identity 构造。 |
ReflectedIndex | 表示反射元素的字典,对应于Index 。 |
反射主键约束 | 表示对应于PrimaryKeyConstraint 的反射元素的字典。 |
反射表注释 | 表示对应于Table.comment 属性的反射注释的字典。 |
反射唯一约束 | 表示对应于UniqueConstraint 的反射元素的字典。 |
class sqlalchemy.engine.reflection.Inspector
执行数据库模式检查。
Inspector 充当Dialect
的反射方法的代理,提供一致的接口以及对先前获取的元数据的缓存支持。
通常通过inspect()
函数创建Inspector
对象,可以传递一个Engine
或一个Connection
:
from sqlalchemy import inspect, create_engine
engine = create_engine('...')
insp = inspect(engine)
在上述情况下,与引擎相关联的Dialect
可能选择返回一个提供了特定于该方言目标数据库的附加方法的Inspector
子类。
成员
init(), bind, clear_cache(), default_schema_name, dialect, engine, from_engine(), get_check_constraints(), get_columns(), get_foreign_keys(), get_indexes(), get_materialized_view_names(), get_multi_check_constraints(), get_multi_columns(), get_multi_foreign_keys(), get_multi_indexes(), get_multi_pk_constraint(), get_multi_table_comment(), get_multi_table_options(), get_multi_unique_constraints(), get_pk_constraint(), get_schema_names(), get_sequence_names(), get_sorted_table_and_fkc_names(), get_table_comment(), get_table_names(), get_table_options(), get_temp_table_names(), get_temp_view_names(), get_unique_constraints(), get_view_definition(), get_view_names(), has_index(), has_schema(), has_sequence(), has_table(), info_cache, reflect_table(), sort_tables_on_foreign_key_dependency()
类签名
类sqlalchemy.engine.reflection.Inspector
(sqlalchemy.inspection.Inspectable
)
method __init__(bind: Engine | Connection)
初始化一个新的Inspector
。
自版本 1.4 弃用:Inspector
上的 init() 方法已弃用,并将在将来的版本中移除。请使用 Engine
或 Connection
上的 inspect()
函数以获取 Inspector
。
参数:
bind – 一个Connection
,通常是Engine
或Connection
的实例。
对于特定于方言的 Inspector
实例,请参阅 Inspector.from_engine()
。
attribute bind: Engine | Connection
method clear_cache() → None
重置此Inspector
的缓存。
当检查方法有缓存数据时,在下次调用以获取新数据时会发出 SQL 查询。
从版本 2.0 开始。
attribute default_schema_name
返回当前引擎的数据库用户的方言提供的默认模式名称。
例如,对于 PostgreSQL 通常是 public
,对于 SQL Server 是 dbo
。
attribute dialect: Dialect
attribute engine: Engine
classmethod from_engine(bind: Engine) → Inspector
从给定的引擎或连接构造一个新的特定于方言的 Inspector 对象。
自版本 1.4 弃用:Inspector
上的 from_engine() 方法已弃用,并将在将来的版本中移除。请使用 Engine
或 Connection
上的 inspect()
函数以获取 Inspector
。
参数:
bind – 一个Connection
或者Engine
。
该方法与直接构造函数调用Inspector
不同,在此,Dialect
有机会提供特定于方言的Inspector
实例,该实例可能提供附加方法。
请参阅Inspector
的示例。
method get_check_constraints(table_name: str, schema: str | None = None, **kw: Any) → List[ReflectedCheckConstraint]
返回table_name
中的检查约束信息。
给定字符串table_name
和可选字符串模式,将检查约束信息作为ReflectedCheckConstraint
列表返回。
参数:
-
table_name
– 表的字符串名称。对于特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
**kw
– 要传递给特定方言实现的附加关键字参数。有关更多信息,请参阅使用中的方言的文档。
返回:
字典列表,每个表示检查约束的定义。
另请参阅
Inspector.get_multi_check_constraints()
method get_columns(table_name: str, schema: str | None = None, **kw: Any) → List[ReflectedColumn]
返回table_name
中的列信息。
给定字符串table_name
和可选字符串schema
,将列信息作为ReflectedColumn
列表返回。
参数:
-
table_name
– 表的字符串名称。对于特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
**kw
– 要传递给特定方言实现的附加关键字参数。有关更多信息,请参阅使用中的方言的文档。
返回:
字典列表,每个表示数据库列的定义。
另请参阅
Inspector.get_multi_columns()
。
method get_foreign_keys(table_name: str, schema: str | None = None, **kw: Any) → List[ReflectedForeignKeyConstraint]
返回table_name
中的外键信息。
给定字符串table_name
,以及可选的字符串模式,将外键信息作为ReflectedForeignKeyConstraint
的列表返回。
参数:
-
table_name
– 表格的字符串名称。对于特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
**kw
– 附加的关键字参数,传递给特定方言的实现。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典列表,每个字典表示一个外键定义。
另请参阅
Inspector.get_multi_foreign_keys()
method get_indexes(table_name: str, schema: str | None = None, **kw: Any) → List[ReflectedIndex]
返回有关table_name
中索引的信息。
给定字符串table_name
和可选的字符串模式,将索引信息作为ReflectedIndex
的列表返回。
参数:
-
table_name
– 表格的字符串名称。对于特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
**kw
– 附加的关键字参数,传递给特定方言的实现。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典列表,每个字典表示一个索引的定义。
另请参阅
Inspector.get_multi_indexes()
method get_materialized_view_names(schema: str | None = None, **kw: Any) → List[str]
返回模式中的所有物化视图名称。
参数:
-
schema
– 可选,从非默认模式中检索名称。对于特殊引用,请使用quoted_name
。 -
**kw
– 附加的关键字参数,传递给特定方言的实现。有关更多信息,请参阅正在使用的方言的文档。
版本 2.0 中的新功能。
另请参阅
Inspector.get_view_names()
method get_multi_check_constraints(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, List[ReflectedCheckConstraint]]
返回给定模式中所有表格中检查约束的信息。
可以通过将要使用的名称传递给filter_names
来过滤表格。
对于每个表,值是ReflectedCheckConstraint
的列表。
参数:
-
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
filter_names
– 可选地仅返回此处列出的对象的信息。 -
kind
– 指定要反映的对象类型的ObjectKind
。默认为ObjectKind.TABLE
。 -
scope
– 指定应反映默认、临时或任何表的约束的ObjectScope
。默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,其中键是两元组模式、表名,值是字典列表,每个表示检查约束的定义。如果未提供模式,则模式为None
。
新版本 2.0 中新增。
另请参阅
Inspector.get_check_constraints()
method get_multi_columns(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, List[ReflectedColumn]]
返回给定模式中所有对象中列的信息。
可通过将要用于filter_names
的名称传递来过滤对象。
对于每个表,值是ReflectedColumn
的列表。
参数:
-
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
filter_names
– 可选地仅返回此处列出的对象的信息。 -
kind
– 指定要反映的对象类型的ObjectKind
。默认为ObjectKind.TABLE
。 -
scope
– 指定应反映默认、临时或任何表的列的ObjectScope
。默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,其中键是两元组模式、表名,值是字典列表,每个表示数据库列的定义。如果未提供模式,则模式为None
。
新版本 2.0 中新增。
另请参阅
Inspector.get_columns()
method get_multi_foreign_keys(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, List[ReflectedForeignKeyConstraint]]
返回给定模式中所有表中外键的信息。
可通过将要用于filter_names
的名称传递来过滤表。
对于每个表,值是一个 ReflectedForeignKeyConstraint
列表。
参数:
-
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。要进行特殊引用,请使用quoted_name
。 -
filter_names
– 可选择仅返回此处列出的对象的信息。 -
kind
– 一个指定要反射的对象类型的ObjectKind
。默认为ObjectKind.TABLE
。 -
scope
– 一个指定要反射的默认、临时或任何表的外键的ObjectScope
。默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,其中键是二元组模式、表名,值是字典列表,每个表示外键定义。如果未提供模式,则模式为 None
。
新版本 2.0 中新增。
另请参阅
Inspector.get_foreign_keys()
method get_multi_indexes(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, List[ReflectedIndex]]
返回给定模式中所有对象中的索引的信息。
可通过将名称传递给 filter_names
来过滤对象。
对于每个表,值是一个 ReflectedIndex
列表。
参数:
-
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。要进行特殊引用,请使用quoted_name
。 -
filter_names
– 可选择仅返回此处列出的对象的信息。 -
kind
– 一个指定要反射的对象类型的ObjectKind
。默认为ObjectKind.TABLE
。 -
scope
– 一个指定要反射的默认、临时或任何表的索引的ObjectScope
。默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,其中键是二元组模式、表名,值是字典列表,每个表示索引的定义。如果未提供模式,则模式为 None
。
新版本 2.0 中新增。
另请参阅
Inspector.get_indexes()
method get_multi_pk_constraint(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, ReflectedPrimaryKeyConstraint]
返回给定模式中所有表中主键约束的信息。
可通过将名称传递给 filter_names
来过滤表。
对于每个表,值是 ReflectedPrimaryKeyConstraint
。
参数:
-
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。要进行特殊引用,请使用quoted_name
。 -
filter_names
– 可选地仅返回此处列出的对象的信息。 -
kind
– 一个ObjectKind
,指定要反映的对象类型。默认为ObjectKind.TABLE
。 -
scope
– 一个ObjectScope
,指定应反映默认、临时或任何表的主键。默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给方言特定实现的额外关键字参数。有关更多信息,请参阅所使用的方言的文档。
返回:
一个字典,其中键是二元组 schema,table-name,值是字典,每个表示主键约束的定义。如果未提供模式,则模式为 None
。
2.0 版新功能。
另请参阅
Inspector.get_pk_constraint()
method get_multi_table_comment(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, ReflectedTableComment]
返回给定模式中所有对象的表注释信息。
可通过将要使用的名称传递给 filter_names
进行过滤对象。
对于每个表,值是 ReflectedTableComment
。
对于不支持注释的方言,引发 NotImplementedError
异常。
参数:
-
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。要进行特殊引用,请使用quoted_name
。 -
filter_names
– 可选地仅返回此处列出的对象的信息。 -
kind
– 一个ObjectKind
,指定要反映的对象类型。默认为ObjectKind.TABLE
。 -
scope
– 一个ObjectScope
,指定应反映默认、临时或任何表的注释。默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给方言特定实现的额外关键字参数。有关更多信息,请参阅所使用的方言的文档。
返回:
一个字典,其中键是二元组 schema,table-name,值是字典,表示表注释。如果未提供模式,则模式为 None
。
2.0 版新功能。
另请参阅
Inspector.get_table_comment()
method get_multi_table_options(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, Dict[str, Any]]
返回指定模式中的表创建时指定的选项的字典。
表格可以通过将要使用的名称传递给 filter_names
进行过滤。
目前包括一些适用于 MySQL 和 Oracle 表的选项。
参数:
-
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
filter_names
– 可选择仅返回此处列出的对象的信息。 -
kind
– 一个ObjectKind
,指定要反映的对象类型。默认为ObjectKind.TABLE
。 -
scope
– 一个ObjectScope
,指定应该反映哪些选项的范围,默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给方言特定实现的附加关键字参数。有关更多信息,请参阅所使用方言的文档。
返回值:
一个字典,其中键是两元组 schema,table-name,值是具有表选项的字典。每个字典中返回的键取决于所使用的方言。每个键都以方言名称为前缀。如果未提供模式,则模式为None
。
新版本功能 2.0。
另请参阅
Inspector.get_table_options()
method get_multi_unique_constraints(schema: str | None = None, filter_names: Sequence[str] | None = None, kind: ObjectKind = ObjectKind.TABLE, scope: ObjectScope = ObjectScope.DEFAULT, **kw: Any) → Dict[TableKey, List[ReflectedUniqueConstraint]]
返回有关给定模式中所有表的唯一约束的信息。
表格可以通过将要使用的名称传递给filter_names
来进行过滤。
对于每个表,值是一个ReflectedUniqueConstraint
的列表。
参数:
-
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
filter_names
– 可选择仅返回此处列出的对象的信息。 -
kind
– 一个ObjectKind
,指定要反映的对象类型。默认为ObjectKind.TABLE
。 -
scope
– 一个ObjectScope
,指定应该反映哪些约束的范围,默认为ObjectScope.DEFAULT
。 -
**kw
– 传递给方言特定实现的附加关键字参数。有关更多信息,请参阅所使用方言的文档。
返回值:
一个字典,其中键是两元组 schema,table-name,值是表示唯一约束定义的字典列表。如果未提供模式,则模式为None
。
新版本功能 2.0。
另请参阅
Inspector.get_unique_constraints()
method get_pk_constraint(table_name: str, schema: str | None = None, **kw: Any) → ReflectedPrimaryKeyConstraint
返回有关table_name
中主键约束的信息。
给定字符串table_name
,以及一个可选的字符串模式,返回主键信息作为ReflectedPrimaryKeyConstraint
。
参数:
-
table_name
- 表的字符串名称。要进行特殊引用,请使用quoted_name
。 -
schema
- 字符串模式名称;如果省略,则使用数据库连接的默认模式。要进行特殊引用,请使用quoted_name
。 -
**kw
- 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个表示主键约束定义的字典。
另请参阅
Inspector.get_multi_pk_constraint()
method get_schema_names(**kw: Any) → List[str]
返回所有模式名称。
参数:
**kw - 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅正在使用的方言的文档。
method get_sequence_names(schema: str | None = None, **kw: Any) → List[str]
返回模式中所有序列名称。
参数:
-
schema
- 可选,从非默认模式中检索名称。要进行特殊引用,请使用quoted_name
。 -
**kw
- 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅正在使用的方言的文档。
method get_sorted_table_and_fkc_names(schema: str | None = None, **kw: Any) → List[Tuple[str | None, List[Tuple[str, str | None]]]]
返回特定模式中所引用的表和外键约束名的依赖排序。
这将产生 2 元组(tablename, [(tname, fkname), (tname, fkname), ...])
,其中包含按 CREATE 顺序分组的表名与未被检测为属于循环的外键约束名。最后一个元素将是(None, [(tname, fkname), (tname, fkname), ..])
,其中包含剩余的外键约束名,这些名字需要在事后单独进行 CREATE 步骤,基于表之间的依赖关系。
参数:
-
schema
- 要查询的模式名称,如果不是默认模式。 -
**kw
- 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅正在使用的方言的文档。
另请参阅
Inspector.get_table_names()
sort_tables_and_constraints()
- 与已给定的MetaData
类似的方法。
method get_table_comment(table_name: str, schema: str | None = None, **kw: Any) → ReflectedTableComment
返回关于table_name
的表注释的信息。
给定字符串 table_name
和可选字符串 schema
,将表注释信息返回为 ReflectedTableComment
。
对于不支持注释的方言,引发 NotImplementedError
。
参数:
-
table_name
– 表的字符串名称。要进行特殊引用,请使用quoted_name
。 -
schema
– 模式名称的字符串;如果省略,将使用数据库连接的默认模式。要进行特殊引用,请使用quoted_name
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典,包含表的注释。
自 1.2 版开始新增。
另请参阅
Inspector.get_multi_table_comment()
method get_table_names(schema: str | None = None, **kw: Any) → List[str]
返回特定模式内的所有表名称。
名称预期只是实际表,而不是视图。视图使用 Inspector.get_view_names()
和/或 Inspector.get_materialized_view_names()
方法返回。
参数:
-
schema
– 模式名称。如果将schema
留在None
,则使用数据库的默认模式,否则搜索命名模式。如果数据库不支持命名模式,则如果不将schema
传递为None
,则行为未定义。要进行特殊引用,请使用quoted_name
。 -
**kw
– 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
另请参阅
Inspector.get_sorted_table_and_fkc_names()
MetaData.sorted_tables
method get_table_options(table_name: str, schema: str | None = None, **kw: Any) → Dict[str, Any]
返回在创建给定名称的表时指定的选项字典。
目前包括一些适用于 MySQL 和 Oracle 表的选项。
参数:
-
table_name
– 表的字符串名称。要进行特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
**kw
– 传递给方言特定实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个带有表选项的字典。返回的键取决于正在使用的方言。每个键都以方言名称为前缀。
另请参阅
Inspector.get_multi_table_options()
method get_temp_table_names(**kw: Any) → List[str]
返回当前绑定的临时表名称列表。
大多数方言不支持此方法;目前只有 Oracle、PostgreSQL 和 SQLite 实现了它。
参数:
**kw – 传递给方言特定实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
method get_temp_view_names(**kw: Any) → List[str]
返回当前绑定的临时视图名称列表。
大多数方言不支持此方法;目前只有 PostgreSQL 和 SQLite 实现了它。
参数:
**kw – 传递给方言特定实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
method get_unique_constraints(table_name: str, schema: str | None = None, **kw: Any) → List[ReflectedUniqueConstraint]
返回table_name
中唯一约束的信息。
给定一个字符串table_name
和一个可选的字符串模式,返回ReflectedUniqueConstraint
的唯一约束信息列表。
参数:
-
table_name
– 表的字符串名称。对于特殊引用,请使用quoted_name
。 -
schema
– 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用quoted_name
。 -
**kw
– 传递给方言特定实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
返回:
一个字典列表,每个代表一个唯一约束的定义。
另请参阅
Inspector.get_multi_unique_constraints()
method get_view_definition(view_name: str, schema: str | None = None, **kw: Any) → str
返回名为view_name
的普通或材料化视图的定义。
参数:
-
view_name
– 视图的名称。 -
schema
– 可选,从非默认模式中检索名称。对于特殊引用,请使用quoted_name
。 -
**kw
– 传递给方言特定实现的额外关键字参数。有关更多信息,请参阅正在使用的方言的文档。
method get_view_names(schema: str | None = None, **kw: Any) → List[str]
返回模式中所有非材料化视图名称。
参数:
-
schema
– 可选,从非默认模式中检索名称。要进行特殊引用,请使用quoted_name
。 -
**kw
– 额外的关键字参数,传递给特定方言实现。有关更多信息,请参阅正在使用的方言的文档。
自版本 2.0 起更改:对于以前在此列表中包括材料化视图名称的方言(目前为 PostgreSQL),此方法不再返回材料化视图的名称。应改用Inspector.get_materialized_view_names()
方法。
另请参见
Inspector.get_materialized_view_names()
method has_index(table_name: str, index_name: str, schema: str | None = None, **kw: Any) → bool
检查数据库中特定索引名称的存在。
参数:
-
table_name
– 索引所属的表的名称。 -
index_name
– 要检查的索引的名称。 -
schema
– 如果不是默认模式,则要查询的模式名称。 -
**kw
– 额外的关键字参数,传递给特定方言实现。有关更多信息,请参阅正在使用的方言的文档。
自版本 2.0 起新增。
method has_schema(schema_name: str, **kw: Any) → bool
如果后端具有给定名称的模式,则返回 True。
参数:
-
schema_name
– 要检查的模式的名称。 -
**kw
– 额外的关键字参数,传递给特定方言实现。有关更多信息,请参阅正在使用的方言的文档。
自版本 2.0 起新增。
method has_sequence(sequence_name: str, schema: str | None = None, **kw: Any) → bool
如果后端具有给定名称的序列,则返回 True。
参数:
-
sequence_name
– 序列的名称。 -
schema
– 如果不是默认模式,则要查询的模式名称。 -
**kw
– 额外的关键字参数,传递给特定方言实现。有关更多信息,请参阅正在使用的方言的文档。
自版本 1.4 起新增。
method has_table(table_name: str, schema: str | None = None, **kw: Any) → bool
如果后端具有给定名称的表、视图或临时表,则返回 True。
参数:
-
table_name
– 要检查的表的名称。 -
schema
– 如果不是默认模式,则要查询的模式名称。 -
**kw
– 额外的关键字参数,传递给特定方言实现。有关更多信息,请参阅正在使用的方言的文档。
自版本 1.4 起新增:- Inspector.has_table()
方法替换了 Engine.has_table()
方法。
自版本 2.0 起更改:Inspector.has_table()
现在正式支持检查额外的类似表的对象:
-
任何类型的视图(普通或材料化)
-
任何类型的临时表
以前,这两个检查没有正式指定,不同的方言在行为上会有所不同。方言测试套件现在包括所有这些对象类型的测试,并应该受到所有包含在 SQLAlchemy 中的方言的支持。然而,第三方方言中的支持可能滞后。
attribute info_cache: Dict[Any, Any]
method reflect_table(table: Table, include_columns: Collection[str] | None, exclude_columns: Collection[str] = (), resolve_fks: bool = True, _extend_on: Set[Table] | None = None, _reflect_info: _ReflectionInfo | None = None) → None
给定一个Table
对象,根据内省加载其内部结构。
这是大多数方言用于生成表反射的基础方法。直接使用方式如下:
from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy import inspect
engine = create_engine('...')
meta = MetaData()
user_table = Table('user', meta)
insp = inspect(engine)
insp.reflect_table(user_table, None)
从版本 1.4 开始更改:从reflecttable
改名为reflect_table
参数:
-
table
– 一个Table
实例。 -
include_columns
– 一个包含在反射过程中的字符串列名列表。如果为None
,则反射所有列。
method sort_tables_on_foreign_key_dependency(consider_schemas: Collection[str | None] = (None,), **kw: Any) → List[Tuple[Tuple[str | None, str] | None, List[Tuple[Tuple[str | None, str], str | None]]]]
返回在多个模式中引用的表和外键约束名称的依赖排序。
此方法可以与Inspector.get_sorted_table_and_fkc_names()
进行比较,后者一次只处理一个模式;在这里,该方法是一个通用方法,将同时考虑多个模式,包括解决跨模式外键。
2.0 版本中的新功能。
class sqlalchemy.engine.interfaces.ReflectedColumn
表示与Column
对象对应的反射元素的字典。
ReflectedColumn
结构由get_columns
方法返回。
成员
autoincrement, comment, computed, default, dialect_options, identity, name, nullable, type
类签名
类sqlalchemy.engine.interfaces.ReflectedColumn
(builtins.dict
)
attribute autoincrement: NotRequired[bool]
依赖于数据库的自动增量标志。
此标志指示列是否具有某种数据库端的“自动增量”标志。在 SQLAlchemy 中,其他类型的列也可能充当“自动增量”列,而不一定在其上具有这样的标志。
有关“自动增量”的更多背景信息,请参见Column.autoincrement
。
attribute comment: NotRequired[str | None]
如果存在,则为列的注释。只有一些方言返回此键
attribute computed: NotRequired[ReflectedComputed]
指示此列是由数据库计算的。只有一些方言返回此键。
版本 1.3.16 中的新功能:- 添加了对计算反射的支持。
attribute default: str | None
列的默认表达式作为 SQL 字符串
attribute dialect_options: NotRequired[Dict[str, Any]]
检测到的此反射对象的额外方言特定选项
attribute identity: NotRequired[ReflectedIdentity]
表示此列是一个 IDENTITY 列。只有一些方言返回此键。
版本 1.4 中的新功能:- 添加了对标识列反射的支持。
attribute name: str
列名
attribute nullable: bool
列的布尔标志,如果列是 NULL 或 NOT NULL。
attribute type: TypeEngine[Any]
作为TypeEngine
实例表示的列类型。
class sqlalchemy.engine.interfaces.ReflectedComputed
表示计算列的反射元素,对应于Computed
构造。
ReflectedComputed
结构是ReflectedColumn
结构的一部分,由Inspector.get_columns()
方法返回。
成员
持久化,sqltext
类签名
类sqlalchemy.engine.interfaces.ReflectedComputed
(builtins.dict
)
attribute persisted: NotRequired[bool]
指示值是存储在表中还是按需计算的
attribute sqltext: str
用于生成此列的表达式,以字符串 SQL 表达式返回
class sqlalchemy.engine.interfaces.ReflectedCheckConstraint
表示反映与CheckConstraint
对应的元素的字典。
ReflectedCheckConstraint
结构由Inspector.get_check_constraints()
方法返回。
成员
方言选项,sqltext
类签名
类sqlalchemy.engine.interfaces.ReflectedCheckConstraint
(builtins.dict
)
attribute dialect_options: NotRequired[Dict[str, Any]]
检测到的此检查约束的额外方言特定选项
版本 1.3.8 中的新功能。
attribute sqltext: str
检查约束的 SQL 表达式
class sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint
表示反映的元素的字典,对应于ForeignKeyConstraint
。
ReflectedForeignKeyConstraint
结构由 Inspector.get_foreign_keys()
方法返回。
成员
constrained_columns,options,referred_columns,referred_schema,referred_table
类签名
类sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint
(builtins.dict
)
attribute constrained_columns: List[str]
组成外键的本地列名
attribute options: NotRequired[Dict[str, Any]]
检测到此外键约束的附加选项
attribute referred_columns: List[str]
引用的列名对应于constrained_columns
。
attribute referred_schema: str | None
被引用的表的架构名称
attribute referred_table: str
被引用的表的名称
class sqlalchemy.engine.interfaces.ReflectedIdentity
表示对应于 Identity
构造的反映的 IDENTITY 结构的列。
ReflectedIdentity
结构是 ReflectedColumn
结构的一部分,由 Inspector.get_columns()
方法返回。
成员
always,cache,cycle,increment,maxvalue,minvalue,nomaxvalue,nominvalue,on_null,order,start
类签名
类sqlalchemy.engine.interfaces.ReflectedIdentity
(builtins.dict
)
attribute always: bool
标识列的类型
attribute cache: int | None
提前计算的序列中的未来值的数量。
attribute cycle: bool
允许在达到最大值或最小值时循环。
attribute increment: int
序列的增量值
attribute maxvalue: int
序列的最大值。
attribute minvalue: int
序列的最小值。
attribute nomaxvalue: bool
序列的最大值。
attribute nominvalue: bool
序列的最小值。
attribute on_null: bool
指示 ON NULL
attribute order: bool
如果为 true,则呈现 ORDER 关键字。
attribute start: int
序列的起始索引
class sqlalchemy.engine.interfaces.ReflectedIndex
表示与Index
相对应的反射元素的字典。
ReflectedIndex
结构由Inspector.get_indexes()
方法返回。
成员
列名、列排序、方言选项、重复约束、表达式、包含列、名称、唯一
类签名
类sqlalchemy.engine.interfaces.ReflectedIndex
(builtins.dict
)
attribute column_names: List[str | None]
索引引用的列名。此列表的元素如果是表达式,则为None
,并在expressions
列表中返回。
attribute column_sorting: NotRequired[Dict[str, Tuple[str]]]
可选字典,将列名或表达式映射到排序关键字元组,其中可能包括asc
、desc
、nulls_first
、nulls_last
。
新版本 1.3.5 中新增。
attribute dialect_options: NotRequired[Dict[str, Any]]
此索引的附加特定方言选项
attribute duplicates_constraint: NotRequired[str | None]
表示此索引是否镜像了此名称的约束
attribute expressions: NotRequired[List[str]]
构成索引的表达式。此列表(当存在时)包含普通列名(也在column_names
中)和表达式(在column_names
中为None
)。
attribute include_columns: NotRequired[List[str]]
包含在支持数据库的 INCLUDE 子句中的列。
自版本 2.0 开始弃用:遗留值,将被index_dict["dialect_options"]["<dialect name>_include"]
替换。
attribute name: str | None
索引名称
attribute unique: bool
索引是否具有唯一标志
class sqlalchemy.engine.interfaces.ReflectedPrimaryKeyConstraint
表示与PrimaryKeyConstraint
相对应的反射元素的字典。
ReflectedPrimaryKeyConstraint
结构由 Inspector.get_pk_constraint()
方法返回。
成员
constrained_columns, dialect_options
类签名
类sqlalchemy.engine.interfaces.ReflectedPrimaryKeyConstraint
(builtins.dict
)
attribute constrained_columns: List[str]
组成主键的列名
attribute dialect_options: NotRequired[Dict[str, Any]]
检测到的此主键的附加特定方言选项
class sqlalchemy.engine.interfaces.ReflectedUniqueConstraint
字典表示对应于 UniqueConstraint
的反射元素。
ReflectedUniqueConstraint
结构由 Inspector.get_unique_constraints()
方法返回。
成员
column_names, dialect_options, duplicates_index
类签名
类sqlalchemy.engine.interfaces.ReflectedUniqueConstraint
(builtins.dict
)
attribute column_names: List[str]
组成唯一约束的列名
attribute dialect_options: NotRequired[Dict[str, Any]]
检测到的此唯一约束的附加特定方言选项
attribute duplicates_index: NotRequired[str | None]
指示此唯一约束是否重复使用此名称的索引
class sqlalchemy.engine.interfaces.ReflectedTableComment
字典表示对应于 Table.comment
属性的反射注释。
ReflectedTableComment
结构由 Inspector.get_table_comment()
方法返回。
成员
text
类签名
类sqlalchemy.engine.interfaces.ReflectedTableComment
(builtins.dict
)
attribute text: str | None
注释文本
使用数据库通用类型反射
当反射表的列时,无论是使用Table
的Table.autoload_with
参数,还是使用Inspector
的Inspector.get_columns()
方法,数据类型都将尽可能地特定于目标数据库。这意味着,如果从 MySQL 数据库中反射出一个“整数”数据类型,该类型将由sqlalchemy.dialects.mysql.INTEGER
类表示,其中包括 MySQL 特定的属性,如“display_width”。或者在 PostgreSQL 上,可能会返回 PostgreSQL 特定的数据类型,如sqlalchemy.dialects.postgresql.INTERVAL
或sqlalchemy.dialects.postgresql.ENUM
。
有一个反射的用例,即给定一个Table
要转移到另一个供应商数据库。为了适应这个用例,有一种技术,可以将这些供应商特定的数据类型即时转换为 SQLAlchemy 后端不可知的数据类型,例如上面的示例中的Integer
、Interval
和Enum
。这可以通过拦截列反射并结合DDLEvents.column_reflect()
事件和TypeEngine.as_generic()
方法来实现。
给定一个 MySQL 表(选择 MySQL 是因为 MySQL 具有许多供应商特定的数据类型和选项):
CREATE TABLE IF NOT EXISTS my_table (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
data1 VARCHAR(50) CHARACTER SET latin1,
data2 MEDIUMINT(4),
data3 TINYINT(2)
)
上述表包括 MySQL 专用的整数类型MEDIUMINT
和TINYINT
,以及一个包含 MySQL 专用CHARACTER SET
选项的VARCHAR
。如果我们正常地反映这个表,它将产生一个包含这些 MySQL 特定数据类型和选项的Table
对象:
>>> from sqlalchemy import MetaData, Table, create_engine
>>> mysql_engine = create_engine("mysql+mysqldb://scott:tiger@localhost/test")
>>> metadata_obj = MetaData()
>>> my_mysql_table = Table("my_table", metadata_obj, autoload_with=mysql_engine)
上面的示例将上述表模式反映到一个新的 Table
对象中。然后,为了演示目的,我们可以使用 CreateTable
构造打印出特定于 MySQL 的“CREATE TABLE”语句:
>>> from sqlalchemy.schema import CreateTable
>>> print(CreateTable(my_mysql_table).compile(mysql_engine))
CREATE TABLE my_table (
id INTEGER(11) NOT NULL AUTO_INCREMENT,
data1 VARCHAR(50) CHARACTER SET latin1,
data2 MEDIUMINT(4),
data3 TINYINT(2),
PRIMARY KEY (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
在上面的例子中,保留了特定于 MySQL 的数据类型和选项。如果我们想要一个可以干净地转移到另一个数据库供应商的 Table
,并用 sqlalchemy.dialects.mysql.MEDIUMINT
和 sqlalchemy.dialects.mysql.TINYINT
替换特殊数据类型,则可以选择在此表上“泛型化”数据类型,或以任何我们喜欢的方式更改它们,方法是使用 DDLEvents.column_reflect()
事件建立一个处理程序。自定义处理程序将使用 TypeEngine.as_generic()
方法,通过替换传递给事件处理程序的列字典条目中的 "type"
条目来将上述特定于 MySQL 的类型对象转换为通用类型。此字典的格式在 Inspector.get_columns()
中描述:
>>> from sqlalchemy import event
>>> metadata_obj = MetaData()
>>> @event.listens_for(metadata_obj, "column_reflect")
... def genericize_datatypes(inspector, tablename, column_dict):
... column_dict["type"] = column_dict["type"].as_generic()
>>> my_generic_table = Table("my_table", metadata_obj, autoload_with=mysql_engine)
现在我们得到了一个新的泛型 Table
并且使用 Integer
作为这些数据类型。例如,我们现在可以在 PostgreSQL 数据库上发出“CREATE TABLE”语句:
>>> pg_engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/test", echo=True)
>>> my_generic_table.create(pg_engine)
CREATE TABLE my_table (
id SERIAL NOT NULL,
data1 VARCHAR(50),
data2 INTEGER,
data3 INTEGER,
PRIMARY KEY (id)
)
还要注意,SQLAlchemy 通常会对其他行为做出合理的猜测,例如,MySQL 的 AUTO_INCREMENT
指令在 PostgreSQL 中最接近地表示为 SERIAL
自动增量数据类型。
1.4 版本新增了 TypeEngine.as_generic()
方法,并进一步改进了 DDLEvents.column_reflect()
事件的使用,以便可以方便地将其应用于 MetaData
对象。
反射的局限性
需要注意的是,反射过程仅使用在关系数据库中表示的信息重建Table
元数据。按照定义,此过程无法恢复数据库中实际未存储的模式的方面。无法从反射中获得的状态包括但不限于:
-
客户端默认值,可以是使用
Column
的default
关键字定义的 Python 函数或 SQL 表达式(注意,这与server_default
是分开的,后者是通过反射获得的)。 -
列信息,例如可能已放置在
Column.info
字典中的数据。 -
对于
Column
或Table
的.quote
设置的值。 -
将特定的
Sequence
与给定的Column
相关联。
在许多情况下,关系数据库报告的表元数据格式与 SQLAlchemy 中指定的格式不同。从反射返回的Table
对象不能始终依赖于产生与原始 Python 定义的Table
对象相同的 DDL。发生这种情况的领域包括服务器默认值、与列相关联的序列以及关于约束和数据类型的各种特殊情况。服务器端默认值可能会以转换指令返回(通常情况下,PostgreSQL 会包含一个::<type>
转换)或与最初指定的不同的引用模式。
另一类限制包括仅部分或尚未定义反射的模式结构。最近对反射进行的改进允许反射诸如视图、索引和外键选项之类的内容。截至撰写本文时,像检查约束、表注释和触发器之类的结构并未反射。
列的插入/更新默认值
列的插入和更新默认值是指在针对该行进行插入或更新语句时,为该列创建默认值的函数,前提是对该列的插入或更新语句未提供任何值。也就是说,如果一个表有一个名为“timestamp”的列,并且进行了不包含该列值的插入语句,那么插入默认值将创建一个新值,例如当前时间,该值将用作要插入到“timestamp”列的值。如果语句包含该列的值,则默认值不会发生。
列默认值可以是服务器端函数或与数据库中的架构一起定义的常量值,在 DDL 中,或者作为 SQLAlchemy 直接在 INSERT 或 UPDATE 语句中呈现的 SQL 表达式;它们也可以是由 SQLAlchemy 在将数据传递到数据库之前调用的客户端 Python 函数或常量值。
注意
列默认处理程序不应与拦截和修改传递给语句的插入和更新语句中的值的构造混淆。这称为数据编组,在这里,在将列值发送到数据库之前,应用程序以某种方式修改列值。SQLAlchemy 提供了几种实现这一点的方法,包括使用自定义数据类型、SQL 执行事件以及 ORM 中的自定义验证器以及属性事件。列默认值仅在 SQL DML 语句中的某一列没有值时调用。
SQLAlchemy 提供了一系列关于在插入和更新语句中针对不存在的值进行默认生成函数的特性。选项包括:
-
插入和更新操作中用作默认值的标量值
-
在插入和更新操作中执行的 Python 函数
-
嵌入到插入语句中的 SQL 表达式(或在某些情况下提前执行的表达式)
-
嵌入到更新语句中的 SQL 表达式
-
插入时使用的服务器端默认值
-
用于更新时的服务器端触发器的标记
所有插入/更新默认值的一般规则是,只有当某一列的值未作为execute()
参数传递时,它们才会生效;否则,将使用给定的值。
标量默认值
最简单的默认值是用作列的默认值的标量值:
Table("mytable", metadata_obj, Column("somecolumn", Integer, default=12))
在上述情况下,如果没有提供其他值,则“12”将绑定为插入时的列值。
标量值也可以与 UPDATE 语句关联,但这不是很常见(因为 UPDATE 语句通常正在寻找动态默认值):
Table("mytable", metadata_obj, Column("somecolumn", Integer, onupdate=25))
Python 执行的函数
Column.default
和 Column.onupdate
关键字参数也接受 Python 函数。如果没有为该列提供其他值,则在插入或更新时调用这些函数,并且返回的值将用于列的值。下面说明了一个简单的“序列”,它将递增的计数器分配给主键列:
# a function which counts upwards
i = 0
def mydefault():
global i
i += 1
return i
t = Table(
"mytable",
metadata_obj,
Column("id", Integer, primary_key=True, default=mydefault),
)
应该注意,对于真正的“递增序列”行为,通常应使用数据库的内置功能,这可能包括序列对象或其他自动增量功能。对于主键列,SQLAlchemy 在大多数情况下将自动使用这些功能。请参阅关于 Column
的 API 文档,包括 Column.autoincrement
标志,以及本章后面关于 Sequence
的部分,了解标准主键生成技术的背景。
为了说明 onupdate
,我们将 Python 的 datetime
函数 now
赋值给 Column.onupdate
属性:
import datetime
t = Table(
"mytable",
metadata_obj,
Column("id", Integer, primary_key=True),
# define 'last_updated' to be populated with datetime.now()
Column("last_updated", DateTime, onupdate=datetime.datetime.now),
)
当执行更新语句并且没有为 last_updated
传递值时,将执行 datetime.datetime.now()
Python 函数,并将其返回值用作 last_updated
的值。请注意,我们将 now
提供为函数本身而不是调用它(即后面没有括号) - SQLAlchemy 将在语句执行时执行该函数。
上下文敏感的默认函数
Column.default
和 Column.onupdate
使用的 Python 函数也可以利用当前语句的上下文来确定一个值。语句的上下文是一个内部的 SQLAlchemy 对象,它包含有关正在执行的语句的所有信息,包括其源表达式、与之关联的参数和游标。与默认生成相关的上下文的典型用例是访问正在插入或更新的行上的其他值。要访问上下文,请提供一个接受单个 context
参数的函数:
def mydefault(context):
return context.get_current_parameters()["counter"] + 12
t = Table(
"mytable",
metadata_obj,
Column("counter", Integer),
Column("counter_plus_twelve", Integer, default=mydefault, onupdate=mydefault),
)
上述默认生成函数适用于所有 INSERT 和 UPDATE 语句,其中未提供 counter_plus_twelve
的值,其值将是执行 counter
列的值加上数字 12。
对于使用“executemany”样式执行的单个语句,例如传递给 Connection.execute()
的多个参数集,用户定义的函数将为每组参数集调用一次。对于多值 Insert
构造的用例(例如通过 Insert.values()
方法设置了多个 VALUES 子句),用户定义的函数也将为每组参数集调用一次。
当调用该函数时,上下文对象(DefaultExecutionContext
的子类)中可用特殊方法 DefaultExecutionContext.get_current_parameters()
。该方法返回一个列键到值的字典,表示 INSERT 或 UPDATE 语句的完整值集。在多值 INSERT 构造的情况下,与单个 VALUES 子句对应的参数子集被从完整参数字典中隔离并单独返回。
新版本 1.2 中:添加了 DefaultExecutionContext.get_current_parameters()
方法,它通过提供将多个 VALUES 子句组织成单独参数字典的服务,改进了仍然存在的 DefaultExecutionContext.current_parameters
属性。## 客户端调用的 SQL 表达式
Column.default
和 Column.onupdate
关键字还可以传递 SQL 表达式,大多数情况下,这些表达式将在 INSERT 或 UPDATE 语句中直接呈现。
t = Table(
"mytable",
metadata_obj,
Column("id", Integer, primary_key=True),
# define 'create_date' to default to now()
Column("create_date", DateTime, default=func.now()),
# define 'key' to pull its default from the 'keyvalues' table
Column(
"key",
String(20),
default=select(keyvalues.c.key).where(keyvalues.c.type="type1"),
),
# define 'last_modified' to use the current_timestamp SQL function on update
Column("last_modified", DateTime, onupdate=func.utc_timestamp()),
)
在上面的例子中,create_date
列将在插入语句中使用 now()
SQL 函数的结果填充(根据后端的不同,在大多数情况下编译为 NOW()
或 CURRENT_TIMESTAMP
),而 key
列将使用另一个表的 SELECT 子查询的结果填充。当为该表发出更新语句时,last_modified
列将填充为 SQL UTC_TIMESTAMP()
MySQL 函数的值。
注意
在使用 func
构造与 SQL 函数时,我们“调用”命名函数,例如在 func.now()
中使用括号。这与当我们将 Python 可调用对象指定为默认值时不同,例如 datetime.datetime
,在这种情况下,我们传递函数本身,但我们自己不调用它。对于 SQL 函数,调用 func.now()
返回将“NOW”函数渲染到正在发射的 SQL 中的 SQL 表达式对象。
Column.default
和 Column.onupdate
指定的默认值和更新 SQL 表达式在插入或更新语句发生时由 SQLAlchemy 明确调用,通常在 DML 语句中内联渲染,除了下面列出的特定情况。这与“服务器端”默认值不同,后者是表的 DDL 定义的一部分,例如作为“CREATE TABLE”语句的一部分,这种情况可能更常见。对于服务器端默认值,请参阅下一节 Server-invoked DDL-Explicit Default Expressions。
当通过 Column.default
指示的 SQL 表达式与主键列一起使用时,存在一些情况下,SQLAlchemy 必须“预执行”默认生成 SQL 函数,这意味着它在单独的 SELECT 语句中被调用,并且生成的值作为参数传递给 INSERT。这仅发生在要求返回此主键值的 INSERT 语句的主键列上,其中不能使用 RETURNING 或 cursor.lastrowid
。指定了 insert.inline
标志的 Insert
构造将始终内联渲染默认表达式。
当语句使用单个参数集执行时(即不是“executemany”样式的执行),返回的CursorResult
将包含通过CursorResult.postfetch_cols()
可访问的集合,该集合包含所有具有内联执行默认值的Column
对象的列表。同样,语句绑定的所有参数,包括预先执行的所有 Python 和 SQL 表达式,都存在于CursorResult.last_inserted_params()
或CursorResult.last_updated_params()
集合中的CursorResult
上。CursorResult.inserted_primary_key
集合包含插入行的主键值列表(列表格式,以便单列和复合列主键以相同的格式表示)。 ## 服务器调用的 DDL-显式默认表达式
SQL 表达式默认值的变体是Column.server_default
,在Table.create()
操作期间会放置在 CREATE TABLE 语句中:
t = Table(
"test",
metadata_obj,
Column("abc", String(20), server_default="abc"),
Column("created_at", DateTime, server_default=func.sysdate()),
Column("index_value", Integer, server_default=text("0")),
)
对于上述表格的创建调用将产生:
CREATE TABLE test (
abc varchar(20) default 'abc',
created_at datetime default sysdate,
index_value integer default 0
)
上面的示例说明了Column.server_default
的两种典型用例,即 SQL 函数(在上面的示例中为 SYSDATE)以及服务器端常量值(在上面的示例中为整数“0”)。建议对任何文字 SQL 值使用text()
构造,而不是传递原始值,因为 SQLAlchemy 通常不会对这些值执行任何引号添加或转义。
与客户端生成的表达式类似,Column.server_default
可以适应一般的 SQL 表达式,但通常预期这些将是简单的函数和表达式,而不是像嵌入式 SELECT 这样更复杂的情况。 ## 标记隐式生成的值、时间戳和触发列
列在插入或更新时基于其他服务器端数据库机制生成新值,例如某些平台上的时间戳列所见的数据库特定的自动生成行为,以及在插入或更新时调用的自定义触发器生成新值,可以使用FetchedValue
作为标记:
from sqlalchemy.schema import FetchedValue
t = Table(
"test",
metadata_obj,
Column("id", Integer, primary_key=True),
Column("abc", TIMESTAMP, server_default=FetchedValue()),
Column("def", String(20), server_onupdate=FetchedValue()),
)
FetchedValue
指示符不会影响 CREATE TABLE 的渲染 DDL。相反,它标记列将在 INSERT 或 UPDATE 语句的过程中由数据库填充新值,并且对于支持的数据库,可以用于指示该列应该是 RETURNING 或 OUTPUT 子句的一部分。诸如 SQLAlchemy ORM 之类的工具随后利用此标记以了解如何在此类操作之后获取列的值。特别是,ValuesBase.return_defaults()
方法可与Insert
或Update
构造一起使用,以指示应返回这些值。
有关在 ORM 中使用FetchedValue
的详细信息,请参阅获取服务器生成的默认值。
警告
Column.server_onupdate
指令目前不会生成 MySQL 的“ON UPDATE CURRENT_TIMESTAMP()”子句。请参阅为 MySQL / MariaDB 的 explicit_defaults_for_timestamp 渲染 ON UPDATE CURRENT TIMESTAMP 了解如何生成此子句的背景信息。
另请参阅
获取服务器生成的默认值 ## 定义序列
SQLAlchemy 使用Sequence
对象表示数据库序列,被视为“列默认值”的特例。它仅对显式支持序列的数据库产生影响,其中包括 PostgreSQL、Oracle、MS SQL Server 和 MariaDB 在内的 SQLAlchemy 包含的方言。否则,Sequence
对象将被忽略。
提示
在较新的数据库引擎中,应该优先使用Identity
构造而不是Sequence
生成整数主键值。请参阅 Identity Columns (GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY) 了解此构造的背景信息。
Sequence
可以放置在任何列上作为“默认”生成器,在 INSERT 操作期间使用,并且如果需要,还可以配置为在 UPDATE 操作期间触发。它最常与单个整数主键列一起使用:
table = Table(
"cartitems",
metadata_obj,
Column(
"cart_id",
Integer,
Sequence("cart_id_seq", start=1),
primary_key=True,
),
Column("description", String(40)),
Column("createdate", DateTime()),
)
在上述情况中,表cartitems
与名为cart_id_seq
的序列相关联。对上述表执行MetaData.create_all()
将包括:
CREATE SEQUENCE cart_id_seq START WITH 1
CREATE TABLE cartitems (
cart_id INTEGER NOT NULL,
description VARCHAR(40),
createdate TIMESTAMP WITHOUT TIME ZONE,
PRIMARY KEY (cart_id)
)
提示
当使用具有显式模式名称的表时(详见指定模式名称),Table
的配置模式不会自动与嵌入的Sequence
共享,而是需要指定Sequence.schema
:
Sequence("cart_id_seq", start=1, schema="some_schema")
Sequence
还可以自动使用正在使用的MetaData
中的MetaData.schema
设置;有关背景,请参阅将序列与 MetaData 关联。
当针对cartitems
表调用Insert
DML 构造时,如果未传递cart_id
列的显式值,则将使用cart_id_seq
序列在参与的后端生成值。通常,序列函数被嵌入到 INSERT 语句中,与 RETURNING 结合使用,以便将新生成的值返回给 Python 进程:
INSERT INTO cartitems (cart_id, description, createdate)
VALUES (next_val(cart_id_seq), 'some description', '2015-10-15 12:00:15')
RETURNING cart_id
当使用Connection.execute()
调用Insert
构造时,包括但不限于使用Sequence
生成的新生成的主键标识符,可通过CursorResult
构造的CursorResult.inserted_primary_key
属性获取。
当Sequence
与Column
作为其Python 端默认生成器关联时,Sequence
也将受到“CREATE SEQUENCE”和“DROP SEQUENCE” DDL 的影响,当为拥有的Table
发出类似 DDL 时,比如使用MetaData.create_all()
为一系列表生成 DDL 时。
Sequence
也可以直接与MetaData
构造关联。这允许Sequence
同时用于多个Table
,并且还允许继承MetaData.schema
参数。请参见将序列与 MetaData 关联部分了解背景信息。
在 SERIAL 列上关联序列
PostgreSQL 的 SERIAL 数据类型是一个自增类型,意味着在发出 CREATE TABLE 时隐式创建一个 PostgreSQL 序列。当为Column
指定Sequence
构造时,可以通过为Sequence.optional
参数指定True
的值来指示在这种特定情况下不应使用它。这允许给定的Sequence
用于没有其他主键生成系统的后端,但在后端(如 PostgreSQL)中会自动生成特定列的序列时忽略它:
table = Table(
"cartitems",
metadata_obj,
Column(
"cart_id",
Integer,
# use an explicit Sequence where available, but not on
# PostgreSQL where SERIAL will be used
Sequence("cart_id_seq", start=1, optional=True),
primary_key=True,
),
Column("description", String(40)),
Column("createdate", DateTime()),
)
在上面的示例中,对于 PostgreSQL 的CREATE TABLE
将使用SERIAL
数据类型来创建cart_id
列,而cart_id_seq
序列将被忽略。然而在 Oracle 上,cart_id_seq
序列将被显式创建。
提示
SERIAL 和 SEQUENCE 的这种特定交互相当传统,就像其他情况一样,使用Identity
将简化操作,只需在所有支持的后端上使用IDENTITY
即可。
单独执行序列
SEQUENCE 是 SQL 中的一类一流模式对象,可用于独立生成数据库中的值。如果有一个Sequence
对象,可以通过直接将其传递给 SQL 执行方法来调用其“next value”指令:
with my_engine.connect() as conn:
seq = Sequence("some_sequence", start=1)
nextid = conn.execute(seq)
为了将Sequence
的“next value”函数嵌入 SQL 语句(如 SELECT 或 INSERT)中,使用Sequence.next_value()
方法,在语句编译时会生成适用于目标后端的 SQL 函数:
>>> my_seq = Sequence("some_sequence", start=1)
>>> stmt = select(my_seq.next_value())
>>> print(stmt.compile(dialect=postgresql.dialect()))
SELECT nextval('some_sequence') AS next_value_1
将序列与 MetaData 关联
对于要与任意Table
对象关联的Sequence
,可以使用Sequence.metadata
参数将Sequence
与特定的MetaData
关联:
seq = Sequence("my_general_seq", metadata=metadata_obj, start=1)
这样的序列可以按照通常的方式与列关联:
table = Table(
"cartitems",
metadata_obj,
seq,
Column("description", String(40)),
Column("createdate", DateTime()),
)
在上面的示例中,Sequence
对象被视为独立的模式构造,可以独立存在或在表之间共享。
明确将Sequence
与MetaData
关联允许以下行为:
-
Sequence
将继承目标MetaData
指定的MetaData.schema
参数,这会影响 CREATE / DROP DDL 的生成以及Sequence.next_value()
函数在 SQL 语句中的呈现方式。 -
MetaData.create_all()
和MetaData.drop_all()
方法将发出 CREATE / DROP 命令,即使此Sequence
没有与任何属于此MetaData
的Table
/Column
关联。
将序列关联为服务器端默认值
注意
以下技术仅已知适用于 PostgreSQL 数据库。它不适用于 Oracle。
上文说明了如何将 Sequence
关联到 Column
作为 Python 端的默认生成器:
Column(
"cart_id",
Integer,
Sequence("cart_id_seq", metadata=metadata_obj, start=1),
primary_key=True,
)
在上述情况下,当相关的 Table
被创建 / 删除时,Sequence
将自动受到 CREATE SEQUENCE / DROP SEQUENCE DDL 的影响。然而,当发出 CREATE TABLE 时,该序列不会作为列的服务器端默认值存在。
如果我们希望序列被用作服务器端默认值,即使我们从 SQL 命令行向表发出 INSERT 命令,它也会生效,我们可以使用 Column.server_default
参数与序列的值生成函数一起使用,该函数可从 Sequence.next_value()
方法中获得。下面我们展示了相同的 Sequence
与 Column
关联,既作为 Python 端的默认生成器,也作为服务器端的默认生成器:
cart_id_seq = Sequence("cart_id_seq", metadata=metadata_obj, start=1)
table = Table(
"cartitems",
metadata_obj,
Column(
"cart_id",
Integer,
cart_id_seq,
server_default=cart_id_seq.next_value(),
primary_key=True,
),
Column("description", String(40)),
Column("createdate", DateTime()),
)
或者使用 ORM:
class CartItem(Base):
__tablename__ = "cartitems"
cart_id_seq = Sequence("cart_id_seq", metadata=Base.metadata, start=1)
cart_id = Column(
Integer, cart_id_seq, server_default=cart_id_seq.next_value(), primary_key=True
)
description = Column(String(40))
createdate = Column(DateTime)
当发出“CREATE TABLE”语句时,在 PostgreSQL 上,它将被表述为:
CREATE TABLE cartitems (
cart_id INTEGER DEFAULT nextval('cart_id_seq') NOT NULL,
description VARCHAR(40),
createdate TIMESTAMP WITHOUT TIME ZONE,
PRIMARY KEY (cart_id)
)
在 Python 端和服务器端默认生成上下文中放置Sequence
可确保“主键获取”逻辑在所有情况下都能正常工作。通常,支持序列的数据库也支持 INSERT 语句的 RETURNING,当发出此语句时,SQLAlchemy 会自动使用。但是,如果对于特定的插入操作不使用 RETURNING,则 SQLAlchemy 更倾向于在 INSERT 语句之外“预执行”序列,这仅在将序列包含为 Python 端默认生成函数时才有效。
该示例还直接将Sequence
与封闭的MetaData
关联,这再次确保Sequence
与MetaData
集合的参数完全关联,包括默认模式(如果有)。
另请参阅
Sequences/SERIAL/IDENTITY - 在 PostgreSQL 方言文档中
RETURNING 支持 - 在 Oracle 方言文档中 ## 计算列 (GENERATED ALWAYS AS)
版本 1.3.11 中的新功能。
Computed
构造允许在 DDL 中声明一个“GENERATED ALWAYS AS”列的Column
,即一个由数据库服务器计算值的列。该构造接受一个 SQL 表达式,通常使用字符串或text()
构造进行文本声明,类似于CheckConstraint
的方式。然后数据库服务器解释 SQL 表达式以确定行内列的值。
示例:
from sqlalchemy import Table, Column, MetaData, Integer, Computed
metadata_obj = MetaData()
square = Table(
"square",
metadata_obj,
Column("id", Integer, primary_key=True),
Column("side", Integer),
Column("area", Integer, Computed("side * side")),
Column("perimeter", Integer, Computed("4 * side")),
)
在 PostgreSQL 12 后端运行时,square
表的 DDL 如下所示:
CREATE TABLE square (
id SERIAL NOT NULL,
side INTEGER,
area INTEGER GENERATED ALWAYS AS (side * side) STORED,
perimeter INTEGER GENERATED ALWAYS AS (4 * side) STORED,
PRIMARY KEY (id)
)
值在 INSERT 和 UPDATE 时是否持久化,或者在获取时是否计算,是数据库的实现细节;前者称为“stored”,后者称为“virtual”。一些数据库实现支持两者,但有些只支持其中一个。可以指定可选的Computed.persisted
标志为 True
或 False
,以指示在 DDL 中是否应该呈现“STORED”或“VIRTUAL”关键字,但是如果目标后端不支持该关键字,则会引发错误;如果不设置,将为目标后端使用一个有效的默认值。
Computed
构造是 FetchedValue
对象的子类,将自己设置为目标 Column
的“服务器默认值”和“服务器更新”生成器,这意味着在生成 INSERT 和 UPDATE 语句时,它将被视为默认生成列,并且在使用 ORM 时将被作为生成列获取。这包括在数据库支持 RETURNING 且要急切地获取生成值时,它将成为数据库的 RETURNING 子句的一部分。
注意
使用 Computed
构造定义的 Column
可能不会存储除服务器应用于其外的任何值; 当为此类列传递值以在 INSERT 或 UPDATE 中写入时,SQLAlchemy 的行为目前是忽略该值。
“GENERATED ALWAYS AS” 目前已知受到支持的数据库有:
-
MySQL 版本 5.7 及更高版本
-
MariaDB 10.x 系列及更高版本
-
PostgreSQL 版本 12 及更高版本
-
Oracle - 值得注意的是,RETURNING 在 UPDATE 中不正确地工作(当包含计算列的 UPDATE..RETURNING 被渲染时,会发出此警告)
-
Microsoft SQL Server
-
SQLite 版本 3.31
当 Computed
与不受支持的后端一起使用时,如果目标方言不支持它,则在尝试渲染构造时会引发 CompileError
。否则,如果方言支持它但正在使用的特定数据库服务器版本不支持它,则在将 DDL 发送到数据库时会引发 DBAPIError
的子类,通常是 OperationalError
。
另请参阅
Computed
## 标识列(GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY)
版本 1.4 中新增。
Identity
构造允许将 Column
声明为标识列,并在 DDL 中渲染为 “GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY”。标识列的值是由数据库服务器自动使用递增(或递减)序列生成的。该构造与 Sequence
共享控制数据库行为的大多数选项。
示例:
from sqlalchemy import Table, Column, MetaData, Integer, Identity, String
metadata_obj = MetaData()
data = Table(
"data",
metadata_obj,
Column("id", Integer, Identity(start=42, cycle=True), primary_key=True),
Column("data", String),
)
在 PostgreSQL 12 后端运行时,data
表的 DDL 如下所示:
CREATE TABLE data (
id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 42 CYCLE) NOT NULL,
data VARCHAR,
PRIMARY KEY (id)
)
数据库将在插入时为 id
列生成值,从 42
开始,如果语句中尚未包含 id
列的值。标识列还可以要求数据库生成列的值,忽略语句中传递的值或引发错误,具体取决于后端。要激活此模式,请在 Identity
构造中将参数 Identity.always
设置为 True
。更新前面的示例以包含此参数将生成以下 DDL:
CREATE TABLE data (
id INTEGER GENERATED ALWAYS AS IDENTITY (START WITH 42 CYCLE) NOT NULL,
data VARCHAR,
PRIMARY KEY (id)
)
Identity
构造是 FetchedValue
对象的子类,并且将自身设置为目标 Column
的“服务器默认”生成器,这意味着当生成 INSERT 语句时,它将被视为默认生成列,以及在使用 ORM 时,它将被作为生成列提取。这包括对于支持 RETURNING 的数据库,它将成为 RETURNING 子句的一部分,并且生成的值将被急切地提取。
目前已知支持 Identity
构造的数据库有:
-
PostgreSQL 版本为 10。
-
Oracle 版本为 12。 还支持传递
always=None
以启用默认生成模式,并传递参数on_null=True
以指定在使用 “BY DEFAULT” 标识列时“ON NULL”。 -
Microsoft SQL Server。 MSSQL 使用自定义语法,仅支持
start
和increment
参数,并忽略所有其他参数。
当与不受支持的后端一起使用时,Identity
将被忽略,并且将使用默认的 SQLAlchemy 逻辑自动递增列。
当 Column
同时指定 Identity
并将 Column.autoincrement
设置为 False
时,会引发错误。
另请参阅
Identity
默认对象 API
对象名称 | 描述 |
---|---|
ColumnDefault | 列的普通默认值。 |
Computed | 定义生成列,即“GENERATED ALWAYS AS”语法。 |
DefaultClause | 由 DDL 指定的默认列值。 |
DefaultGenerator | 列 默认 值的基类。 |
FetchedValue | 用于透明数据库端默认值的标记。 |
Identity | 定义标识列,即“GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY”语法。 |
Sequence | 表示命名的数据库序列。 |
class sqlalchemy.schema.Computed
定义一个生成列,即“GENERATED ALWAYS AS”语法。
Computed
构造是一个内联构造,添加到 Column
对象的参数列表中:
from sqlalchemy import Computed
Table('square', metadata_obj,
Column('side', Float, nullable=False),
Column('area', Float, Computed('side * side'))
)
详细信息请参阅下面链接的文档。
新于版本 1.3.11。
请参阅
计算列(GENERATED ALWAYS AS)
成员
init(), copy()
类签名
类sqlalchemy.schema.Computed
(sqlalchemy.schema.FetchedValue
,sqlalchemy.schema.SchemaItem
)
method __init__(sqltext: _DDLColumnArgument, persisted: bool | None = None) → None
构造一个 GENERATED ALWAYS AS DDL 构造,以配合 Column
。
参数:
-
sqltext
–包含列生成表达式的字符串,该表达式将直接使用,或者是一个 SQL 表达式构造,比如
text()
对象。如果以字符串形式给出,则将该对象转换为text()
对象。警告
传递给
Computed
的Computed.sqltext
参数可以作为 Python 字符串参数传递,它将被视为受信任的 SQL 文本并按给定方式呈现。请勿将不受信任的输入传递给此参数。 -
persisted
–可选,控制该列在数据库中的持久化方式。可能的值包括:
-
None
,默认值,它将使用数据库定义的默认持久化方式。 -
True
,将呈现GENERATED ALWAYS AS ... STORED
,或者如果目标数据库支持的话,将呈现等效值。 -
False
,将呈现GENERATED ALWAYS AS ... VIRTUAL
,或者如果目标数据库支持的话,将呈现等效值。
如果数据库不支持该持久化选项,则指定
True
或False
可能会在将 DDL 发出到目标数据库时引发错误。将此参数保留为其默认值None
保证在所有支持GENERATED ALWAYS AS
的数据库上都可以成功。 -
method copy(*, target_table: Table | None = None, **kw: Any) → Computed
自版本 1.4 起已弃用:Computed.copy()
方法已弃用,并将在将来的版本中删除。
class sqlalchemy.schema.ColumnDefault
列上的纯默认值。
这可能对应于一个常量、一个可调用函数或一个 SQL 子句。
ColumnDefault
在 Column
的 default
、onupdate
参数被使用时会自动生成。一个 ColumnDefault
也可以作为位置参数传递。
例如,以下内容:
Column('foo', Integer, default=50)
等价于:
Column('foo', Integer, ColumnDefault(50))
类签名
类 sqlalchemy.schema.ColumnDefault
(sqlalchemy.schema.DefaultGenerator
,abc.ABC
)
class sqlalchemy.schema.DefaultClause
DDL 指定的 DEFAULT 列值。
DefaultClause
是一个 FetchedValue
,当发出 “CREATE TABLE” 时也会生成一个“DEFAULT”子句。
当 Column
的 server_default
、server_onupdate
参数被使用时,DefaultClause
会自动生成。一个 DefaultClause
也可以作为位置参数传递。
例如,以下内容:
Column('foo', Integer, server_default="50")
等价于:
Column('foo', Integer, DefaultClause("50"))
类签名
类 sqlalchemy.schema.DefaultClause
(sqlalchemy.schema.FetchedValue
)
class sqlalchemy.schema.DefaultGenerator
列默认值的基类。
此对象仅出现在 column.default 或 column.onupdate。它不能作为服务器默认值有效。
类签名
类 sqlalchemy.schema.DefaultGenerator
(sqlalchemy.sql.expression.Executable
,sqlalchemy.schema.SchemaItem
)
class sqlalchemy.schema.FetchedValue
用于透明数据库端默认值的标记。
当数据库配置为为列提供一些自动默认值时,请使用 FetchedValue
。
例如:
Column('foo', Integer, FetchedValue())
将指示某个触发器或默认生成器在 INSERT 期间为 foo
列创建一个新值。
另请参阅
标记隐式生成的值、时间戳和触发列
类签名
类 sqlalchemy.schema.FetchedValue
(sqlalchemy.sql.expression.SchemaEventTarget
)
class sqlalchemy.schema.Sequence
表示一个命名的数据库序列。
Sequence
对象表示数据库序列的名称和配置参数。它还表示一个可以被 SQLAlchemy Engine
或 Connection
“执行”的结构,为目标数据库渲染适当的“下一个值”函数并返回结果。
Sequence
通常与主键列关联:
some_table = Table(
'some_table', metadata,
Column('id', Integer, Sequence('some_table_seq', start=1),
primary_key=True)
)
当为上述 Table
发射 CREATE TABLE 时,如果目标平台支持序列,则也会发射 CREATE SEQUENCE 语句。对于不支持序列的平台,将忽略 Sequence
构造。
另请参阅
定义序列
CreateSequence
DropSequence
成员
init(), create(), drop(), next_value()
类签名
类 sqlalchemy.schema.Sequence
(sqlalchemy.schema.HasSchemaAttr
, sqlalchemy.schema.IdentityOptions
, sqlalchemy.schema.DefaultGenerator
)
method __init__(name: str, start: int | None = None, increment: int | None = None, minvalue: int | None = None, maxvalue: int | None = None, nominvalue: bool | None = None, nomaxvalue: bool | None = None, cycle: bool | None = None, schema: str | Literal[SchemaConst.BLANK_SCHEMA] | None = None, cache: int | None = None, order: bool | None = None, data_type: _TypeEngineArgument[int] | None = None, optional: bool = False, quote: bool | None = None, metadata: MetaData | None = None, quote_schema: bool | None = None, for_update: bool = False) → None
构建一个 Sequence
对象。
参数:
-
name
– 序列的名称。 -
start
– 开始索引。序列的起始索引。在将 CREATE SEQUENCE 命令发射到数据库时,此值被用作“START WITH”子句的值。如果为
None
,则省略该子句,大多数平台上表示起始值为 1。从版本 2.0 开始更改:要求
Sequence.start
参数以发射 DDL “START WITH”。这是在版本 1.4 中进行的一项更改的反转,该更改如果未包括Sequence.start
将隐式渲染“START WITH 1”。有关更多详细信息,请参阅 序列结构还原为没有任何显式默认“开始”值;影响 MS SQL Server。 -
increment
– 序列的增量值。在将 CREATE SEQUENCE 命令发射到数据库时,此值被用作“INCREMENT BY”子句的值。如果为None
,则省略该子句,大多数平台上表示增量为 1。 -
minvalue
– 序列的最小值。当向数据库发出 CREATE SEQUENCE 命令时,此值用作“MINVALUE”子句的值。如果为None
,则省略该子句,在大多数平台上表示升序和降序序列的最小值分别为 1 和 -2⁶³-1。 -
maxvalue
– 序列的最大值。当向数据库发出 CREATE SEQUENCE 命令时,此值用作“MAXVALUE”子句的值。如果为None
,则省略该子句,在大多数平台上表示升序和降序序列的最大值分别为 2⁶³-1 和 -1。 -
nominvalue
– 序列没有最小值。当向数据库发出 CREATE SEQUENCE 命令时,此值用作“NO MINVALUE”子句的值。如果为None
,则省略该子句,在大多数平台上表示升序和降序序列的最小值分别为 1 和 -2⁶³-1。 -
nomaxvalue
– 序列没有最大值。当向数据库发出 CREATE SEQUENCE 命令时,此值用作“NO MAXVALUE”子句的值。如果为None
,则省略该子句,在大多数平台上表示升序和降序序列的最大值分别为 2⁶³-1 和 -1。 -
cycle
– 当升序或降序序列达到最大值或最小值时,允许序列环绕。当向数据库发出 CREATE SEQUENCE 命令时,此值用作“CYCLE”子句。如果达到限制,则下一个生成的数字将是最小值或最大值,分别是升序或降序。如果 cycle=False(默认值),在序列达到其最大值后,任何对 nextval 的调用都将返回错误。 -
schema
– 序列的可选模式名称,如果位于默认模式之外的模式中。当MetaData
也存在时,选择模式名称的规则与Table.schema
相同。 -
cache
– 可选整数值;提前计算序列中的未来值的数量。呈现 Oracle 和 PostgreSQL 可理解的 CACHE 关键字。 -
order
– 可选布尔值;如果为True
,则呈现 ORDER 关键字,Oracle 可理解,表示序列是有序的。可能需要使用 Oracle RAC 提供确定性排序。 -
data_type
–序列返回的类型,适用于允许我们在 INTEGER、BIGINT 等之间进行选择的方言(例如,mssql)。
新版本 1.4.0 中新增。
-
optional
– 布尔值,当为True
时,表示此Sequence
对象只需在没有其他方法生成主键标识符的后端上显式生成。目前,这实际上意味着,“在 PostgreSQL 后端上不要创建此序列,因为 SERIAL 关键字会自动为我们创建序列”。 -
quote
– 布尔值,当为True
或False
时,明确地强制引用Sequence.name
的名称,打开或关闭。当保留其默认值None
时,基于大小写和保留字的常规引用规则生效。 -
quote_schema
– 设置对schema
名称的引用首选项。 -
metadata
–可选的
MetaData
对象,此Sequence
将与之关联。与MetaData
关联的Sequence
具有以下功能:-
Sequence
将继承指定给目标MetaData
的MetaData.schema
参数,这会影响 CREATE / DROP DDL 的生成(如果有)。 -
Sequence.create()
和Sequence.drop()
方法会自动使用绑定到MetaData
对象的引擎(如果有)。 -
MetaData.create_all()
和MetaData.drop_all()
方法将为此Sequence
发出 CREATE / DROP,即使此Sequence
未与此MetaData
的任何成员Table
/Column
关联。
上述行为只有在通过此参数将
Sequence
明确关联到MetaData
时才会发生。另请参阅
将序列与 MetaData 关联 - 关于
Sequence.metadata
参数的详细讨论。 -
-
for_update
– 表示当与Column
关联时,此Sequence
应在该列的表上进行 UPDATE 语句调用,而不是在该语句中否则在该列中没有值。
method create(bind: _CreateDropBind, checkfirst: bool = True) → None
在数据库中创建此序列。
method drop(bind: _CreateDropBind, checkfirst: bool = True) → None
从数据库中删除此序列。
method next_value() → Function[int]
返回一个next_value
函数元素,该函数将为此Sequence
在任何 SQL 表达式中呈现适当的增量函数。
class sqlalchemy.schema.Identity
定义一个标识列,即“GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY”语法。
Identity
结构是添加到Column
对象的参数列表中的内联结构:
from sqlalchemy import Identity
Table('foo', metadata_obj,
Column('id', Integer, Identity())
Column('description', Text),
)
请参阅下面链接的文档以获取完整详情。
从版本 1.4 开始新增。
另请参阅
标识列(GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY)
成员
init(), copy()
类签名
类sqlalchemy.schema.Identity
(sqlalchemy.schema.IdentityOptions
,sqlalchemy.schema.FetchedValue
,sqlalchemy.schema.SchemaItem
)
method __init__(always: bool = False, on_null: bool | None = None, start: int | None = None, increment: int | None = None, minvalue: int | None = None, maxvalue: int | None = None, nominvalue: bool | None = None, nomaxvalue: bool | None = None, cycle: bool | None = None, cache: int | None = None, order: bool | None = None) → None
创建一个 DDL 结构GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY
,用于配合Column
。
请参阅Sequence
文档,了解大多数参数的完整描述。
注意
MSSQL 支持此结构作为在列上生成 IDENTITY 的首选替代方案,但它使用的非标准语法仅支持Identity.start
和Identity.increment
。所有其他参数都会被忽略。
参数:
-
always
– 一个布尔值,表示标识列的类型。如果指定了False
,则默认情况下用户指定的值优先。如果指定了True
,则不接受用户指定的值(在某些后端,如 PostgreSQL,可以在插入时指定 OVERRIDING SYSTEM VALUE 或类似语句以覆盖序列值)。某些后端也对此参数有默认值,None
可以用于在 DDL 中省略渲染此部分。如果后端没有默认值,则将其视为False
。 -
on_null
– 设置为True
以与always=False
标识列一起指定 ON NULL。此选项仅在某些后端(如 Oracle)上受支持。 -
start
– 序列的起始索引。 -
increment
– 序列的增量值。 -
minvalue
– 序列的最小值。 -
maxvalue
– 序列的最大值。 -
nominvalue
– 序列的最小值不存在。 -
nomaxvalue
– 序列的最大值不存在。 -
cycle
– 当达到最大值或最小值时允许序列循环。 -
cache
– 可选的整数值;提前计算的序列中未来值的数量。 -
order
– 可选的布尔值;如果为 true,则呈现 ORDER 关键字。
method copy(**kw: Any) → Identity
自版本 1.4 起已弃用:Identity.copy()
方法已弃用,将在将来的版本中移除。
标量默认值
最简单的默认值是作为列默认值使用的标量值:
Table("mytable", metadata_obj, Column("somecolumn", Integer, default=12))
上述,如果未提供其他值,则值“12”将在插入时绑定为列值。
标量值也可能与 UPDATE 语句关联,尽管这不是很常见(因为 UPDATE 语句通常寻找动态默认值):
Table("mytable", metadata_obj, Column("somecolumn", Integer, onupdate=25))
Python 执行的函数
Column.default
和Column.onupdate
关键字参数也接受 Python 函数。如果未提供该列的其他值,则在插入或更新时调用这些函数,并使用返回的值作为列的值。以下示例说明了一个粗糙的“序列”,将递增计数器分配给主键列:
# a function which counts upwards
i = 0
def mydefault():
global i
i += 1
return i
t = Table(
"mytable",
metadata_obj,
Column("id", Integer, primary_key=True, default=mydefault),
)
应该注意,对于真正的“增量序列”行为,通常应该使用数据库的内置功能,这可能包括序列对象或其他自增能力。对于主键列,SQLAlchemy 在大多数情况下将自动使用这些功能。请参阅Column
的 API 文档,包括Column.autoincrement
标志,以及本章后面关于Sequence
的部分,了解标准主键生成技术的背景。
为了说明 onupdate,我们将 Python 的datetime
函数now
赋值给Column.onupdate
属性:
import datetime
t = Table(
"mytable",
metadata_obj,
Column("id", Integer, primary_key=True),
# define 'last_updated' to be populated with datetime.now()
Column("last_updated", DateTime, onupdate=datetime.datetime.now),
)
当执行更新语句并且未传递last_updated
值时,将执行datetime.datetime.now()
Python 函数,并将其返回值用作last_updated
的值。请注意,我们将now
作为函数本身提供,而不调用它(即后面没有括号)- SQLAlchemy 将在执行语句时执行该函数。
上下文敏感的默认函数
Column.default
和Column.onupdate
使用的 Python 函数也可以利用当前语句上下文来确定值。语句的上下文是一个内部的 SQLAlchemy 对象,包含有关正在执行的语句的所有信息,包括其源表达式、与之关联的参数和游标。在默认生成的上下文中,典型的用例是访问正在插入或更新的行上的其他值。要访问上下文,请提供一个接受单个context
参数的函数:
def mydefault(context):
return context.get_current_parameters()["counter"] + 12
t = Table(
"mytable",
metadata_obj,
Column("counter", Integer),
Column("counter_plus_twelve", Integer, default=mydefault, onupdate=mydefault),
)
上述默认生成函数是这样应用的:它将用于所有未提供counter_plus_twelve
值的 INSERT 和 UPDATE 语句,并且该值将是执行counter
列时的任何值加上 12 的值。
对于使用“executemany”样式执行的单个语句,例如通过Connection.execute()
传递多个参数集的情况,用户定义的函数将为每组参数集调用一次。对于多值Insert
结构的用例(例如通过Insert.values()
方法设置了多个 VALUES 子句),用户定义的函数也将为每组参数集调用一次。
当函数被调用时,上下文对象(DefaultExecutionContext
的一个子类)中可用的特殊方法DefaultExecutionContext.get_current_parameters()
。此方法返回一个字典,其中键-值对表示 INSERT 或 UPDATE 语句的完整值集。在多值 INSERT 结构的情况下,与单个 VALUES 子句对应的参数子集将从完整参数字典中隔离并单独返回。
1.2 版中的新功能:增加了DefaultExecutionContext.get_current_parameters()
方法,它改进了仍然存在的DefaultExecutionContext.current_parameters
属性,通过提供将多个 VALUES 子句组织成单独参数字典的服务。### 上下文敏感的默认函数
由Column.default
和Column.onupdate
使用的 Python 函数还可以利用当前语句的上下文来确定一个值。语句的上下文是一个内部的 SQLAlchemy 对象,其中包含关于正在执行的语句的所有信息,包括其源表达式、与之关联的参数和游标。与默认生成相关的此上下文的典型用例是访问要插入或更新的行上的其他值。要访问上下文,请提供一个接受单个context
参数的函数:
def mydefault(context):
return context.get_current_parameters()["counter"] + 12
t = Table(
"mytable",
metadata_obj,
Column("counter", Integer),
Column("counter_plus_twelve", Integer, default=mydefault, onupdate=mydefault),
)
上述默认生成函数被应用于所有 INSERT 和 UPDATE 语句,其中未提供counter_plus_twelve
的值,并且该值将为执行counter
列时存在的任何值加上 12。
对于使用“executemany”风格执行的单个语句,例如向 Connection.execute()
传递多个参数集的情况,用户定义的函数会为每个参数集调用一次。对于多值 Insert
结构的用例(例如通过 Insert.values()
方法设置了多个 VALUES 子句),用户定义的函数也会为每个参数集调用一次。
当函数被调用时,上下文对象(DefaultExecutionContext
的子类)中可用特殊方法DefaultExecutionContext.get_current_parameters()
。该方法返回一个字典,列键到值的映射,表示 INSERT 或 UPDATE 语句的完整值集。对于多值 INSERT 结构的情况,与单个 VALUES 子句对应的参数子集被从完整参数字典中隔离并单独返回。
1.2 版本中新增:增加了 DefaultExecutionContext.get_current_parameters()
方法,它改进了仍然存在的 DefaultExecutionContext.current_parameters
属性,提供了将多个 VALUES 子句组织成单独参数字典的服务。
客户端调用的 SQL 表达式
也可以传递 SQL 表达式给 Column.default
和 Column.onupdate
关键字,这在大多数情况下会在 INSERT 或 UPDATE 语句中内联呈现:
t = Table(
"mytable",
metadata_obj,
Column("id", Integer, primary_key=True),
# define 'create_date' to default to now()
Column("create_date", DateTime, default=func.now()),
# define 'key' to pull its default from the 'keyvalues' table
Column(
"key",
String(20),
default=select(keyvalues.c.key).where(keyvalues.c.type="type1"),
),
# define 'last_modified' to use the current_timestamp SQL function on update
Column("last_modified", DateTime, onupdate=func.utc_timestamp()),
)
在上述情况中,create_date
列将在 INSERT 语句期间填充 now()
SQL 函数的结果(在大多数情况下,根据后端编译为 NOW()
或 CURRENT_TIMESTAMP
),而 key
列将填充另一张表的 SELECT 子查询的结果。当为此表发出 UPDATE 语句时,last_modified
列将填充 SQL UTC_TIMESTAMP()
MySQL 函数的值。
注意
使用func
构造和 SQL 函数时,我们会“调用”命名函数,例如在 func.now()
中使用括号。这与当我们将 Python 可调用对象(例如 datetime.datetime
)指定为默认值时不同,其中我们传递函数本身,但我们不自己调用它。对于 SQL 函数,调用func.now()
将返回将“NOW”函数呈现为正在发出的 SQL 中的 SQL 表达式对象。
当发生 INSERT 或 UPDATE 语句时,SQLAlchemy 在 Column.default
和 Column.onupdate
指定的默认和更新 SQL 表达式明确调用它们,通常在 DML 语句中内联渲染,除了下面列出的某些情况。这与“服务器端”默认值不同,后者是表的 DDL 定义的一部分,例如作为“CREATE TABLE”语句的一部分,这可能更常见。有关服务器端默认值,请参阅下一节服务器调用 DDL-显式默认表达式。
当由Column.default
指示的 SQL 表达式与主键列一起使用时,有些情况下 SQLAlchemy 必须“预先执行”默认生成的 SQL 函数,这意味着它在单独的 SELECT 语句中被调用,并且生成的值作为参数传递给 INSERT。这仅发生在主键列为 INSERT 语句被要求返回该主键值的情况下,其中不能使用 RETURNING 或 cursor.lastrowid
。指定了insert.inline
标志的 Insert
构造将始终将默认表达式呈现为内联。
当执行语句使用单一参数集合(即不是“executemany”风格执行)时,返回的CursorResult
将包含一个可通过CursorResult.postfetch_cols()
访问的集合,其中包含所有具有内联执行默认值的Column
对象的列表。同样,绑定到语句的所有参数,包括所有预先执行的 Python 和 SQL 表达式,都存在于CursorResult.last_inserted_params()
或CursorResult.last_updated_params()
集合中的CursorResult
。CursorResult.inserted_primary_key
集合包含插入的行的主键值列表(列表使得单列和复合列主键以相同格式表示)。
服务器调用的 DDL 显式默认表达式
SQL 表达式默认的一种变体是Column.server_default
,在Table.create()
操作期间会被放置在 CREATE TABLE 语句中:
t = Table(
"test",
metadata_obj,
Column("abc", String(20), server_default="abc"),
Column("created_at", DateTime, server_default=func.sysdate()),
Column("index_value", Integer, server_default=text("0")),
)
对上述表的创建调用将产生:
CREATE TABLE test (
abc varchar(20) default 'abc',
created_at datetime default sysdate,
index_value integer default 0
)
上述示例说明了Column.server_default
的两种典型用法,即 SQL 函数(上述示例中的 SYSDATE)以及服务器端常量值(上述示例中的整数“0”)。建议对任何文字 SQL 值使用text()
构造,而不是传递原始值,因为 SQLAlchemy 通常不对这些值执行任何引用或转义。
与客户端生成的表达式类似,Column.server_default
可以容纳一般的 SQL 表达式,但是预期这些通常会是简单的函数和表达式,而不是更复杂的情况,比如嵌套的 SELECT。
标记隐式生成的值、时间戳和触发列
当插入或更新时,基于其他服务器端数据库机制生成新值的列,例如在某些平台上与时间戳列一起看到的数据库特定的自动生成行为,以及在插入或更新时调用的自定义触发器以生成新值,可以使用FetchedValue
作为标记:
from sqlalchemy.schema import FetchedValue
t = Table(
"test",
metadata_obj,
Column("id", Integer, primary_key=True),
Column("abc", TIMESTAMP, server_default=FetchedValue()),
Column("def", String(20), server_onupdate=FetchedValue()),
)
FetchedValue
指示器不会影响 CREATE TABLE 的渲染 DDL。相反,它标记了在 INSERT 或 UPDATE 语句的过程中由数据库填充新值的列,并且对于支持的数据库,可能会用于指示该列应该是 RETURNING 或 OUTPUT 子句的一部分。然后,诸如 SQLAlchemy ORM 之类的工具使用此标记来了解如何获取此类操作后列的值。特别是,可以使用ValuesBase.return_defaults()
方法与Insert
或Update
构造来指示应返回这些值。
有关使用 ORM 中的FetchedValue
的详细信息,请参阅获取服务器生成的默认值。
警告
Column.server_onupdate
指令目前不会生成 MySQL 的“ON UPDATE CURRENT_TIMESTAMP()”子句。有关如何生成此子句的背景信息,请参阅为 MySQL / MariaDB 的 explicit_defaults_for_timestamp 渲染 ON UPDATE CURRENT TIMESTAMP。
另请参阅
获取服务器生成的默认值
定义序列
SQLAlchemy 使用Sequence
对象表示数据库序列,这被认为是“列默认值”的特殊情况。它仅对具有对序列的明确支持的数据库产生影响,其中包括 SQLAlchemy 包含的方言中的 PostgreSQL、Oracle、MS SQL Server 和 MariaDB。否则,Sequence
对象将被忽略。
提示
在较新的数据库引擎中,应该优先使用Identity
构造生成整数主键值,而不是Sequence
。有关此构造的背景信息,请参阅 Identity Columns (GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY)。
Sequence
可以放置在任何列上作为“默认”生成器,在 INSERT 操作期间使用,并且如果需要,还可以配置在 UPDATE 操作期间触发。它通常与单个整数主键列一起使用:
table = Table(
"cartitems",
metadata_obj,
Column(
"cart_id",
Integer,
Sequence("cart_id_seq", start=1),
primary_key=True,
),
Column("description", String(40)),
Column("createdate", DateTime()),
)
在上述情况下,表cartitems
与名为cart_id_seq
的序列相关联。发出上述表的MetaData.create_all()
将包括:
CREATE SEQUENCE cart_id_seq START WITH 1
CREATE TABLE cartitems (
cart_id INTEGER NOT NULL,
description VARCHAR(40),
createdate TIMESTAMP WITHOUT TIME ZONE,
PRIMARY KEY (cart_id)
)
提示
当使用具有显式模式名称的表(详细信息请参阅指定模式名称)时,Table
的配置模式不会自动由嵌入的Sequence
共享,而是需要指定Sequence.schema
:
Sequence("cart_id_seq", start=1, schema="some_schema")
Sequence
也可以自动使用正在使用的MetaData
的设置中的MetaData.schema
;有关背景信息,请参阅将序列与 MetaData 关联。
当针对cartitems
表调用Insert
DML 构造时,如果没有为cart_id
列传递显式值,则cart_id_seq
序列将用于在参与的后端生成一个值。通常,序列函数嵌入在 INSERT 语句中,与 RETURNING 结合在一起,以便新生成的值可以返回给 Python 进程:
INSERT INTO cartitems (cart_id, description, createdate)
VALUES (next_val(cart_id_seq), 'some description', '2015-10-15 12:00:15')
RETURNING cart_id
当使用Connection.execute()
来调用Insert
构造时,包括但不限于使用Sequence
生成的新生成的主键标识符,可以通过CursorResult
构造使用CursorResult.inserted_primary_key
属性获得。
当将 Sequence
关联到 Column
作为其 Python-side 默认生成器时,当为拥有 Table
发出类似 DDL 的情况下,例如使用 MetaData.create_all()
为一系列表生成 DDL 时,该 Sequence
也将受到 “CREATE SEQUENCE” 和 “DROP SEQUENCE” DDL 的约束。
Sequence
也可以直接与 MetaData
构造关联。这允许 Sequence
在多个 Table
中同时使用,并且还允许继承 MetaData.schema
参数。有关详情,请参见 将序列与元数据关联 部分。
在 SERIAL 列上关联一个序列
PostgreSQL 的 SERIAL 数据类型是一种自增类型,意味着在发出 CREATE TABLE 命令时隐式创建了一个 PostgreSQL 序列。当为 Column
指定了 Sequence
构造时,可以通过将 Sequence.optional
参数的值设置为 True
来指示在这种特定情况下不应使用它。这允许给定的 Sequence
用于没有其他替代主键生成系统的后端,但对于自动为特定列生成序列的后端(例如 PostgreSQL),可以忽略它:
table = Table(
"cartitems",
metadata_obj,
Column(
"cart_id",
Integer,
# use an explicit Sequence where available, but not on
# PostgreSQL where SERIAL will be used
Sequence("cart_id_seq", start=1, optional=True),
primary_key=True,
),
Column("description", String(40)),
Column("createdate", DateTime()),
)
在上面的示例中,对于 PostgreSQL,CREATE TABLE
将使用 SERIAL
数据类型来创建 cart_id
列,并且 cart_id_seq
序列将被忽略。然而在 Oracle 中,cart_id_seq
序列将被显式创建。
提示
SERIAL 和 SEQUENCE 的这种特定交互在相当程度上是遗留的,在其他情况下,使用 Identity
将简化操作,只需在所有支持的后端上使用 IDENTITY
即可。
执行一个独立的序列
SEQUENCE 是 SQL 中的一种一流模式对象,可用于在数据库中独立生成值。如果有 Sequence
对象,可以通过直接将其传递给 SQL 执行方法来调用其“next value”指令:
with my_engine.connect() as conn:
seq = Sequence("some_sequence", start=1)
nextid = conn.execute(seq)
为了将 Sequence
的“next value”函数嵌入到类似于 SELECT 或 INSERT 的 SQL 语句中,可以使用 Sequence.next_value()
方法,该方法将在语句编译时生成适用于目标后端的 SQL 函数:
>>> my_seq = Sequence("some_sequence", start=1)
>>> stmt = select(my_seq.next_value())
>>> print(stmt.compile(dialect=postgresql.dialect()))
SELECT nextval('some_sequence') AS next_value_1
将序列与 MetaData 关联
对于将与任意 Table
对象关联的 Sequence
,可以使用 Sequence.metadata
参数将 Sequence
关联到特定的 MetaData
:
seq = Sequence("my_general_seq", metadata=metadata_obj, start=1)
然后可以以通常的方式将这样的序列与列关联起来:
table = Table(
"cartitems",
metadata_obj,
seq,
Column("description", String(40)),
Column("createdate", DateTime()),
)
在上面的示例中,Sequence
对象被视为独立的模式构造,可以独立存在或在表之间共享。
明确将 Sequence
与 MetaData
关联允许以下行为:
-
Sequence
将继承指定给目标MetaData
的MetaData.schema
参数,这影响了 CREATE / DROP DDL 的生成以及 SQL 语句中Sequence.next_value()
函数的呈现方式。 -
MetaData.create_all()
和MetaData.drop_all()
方法将发出 CREATE / DROP 用于此Sequence
,即使该Sequence
未与任何此MetaData
的成员Table
/Column
相关联。
将序列关联为服务器端默认值
注意
以下技术仅在 PostgreSQL 数据库中有效,不适用于 Oracle。
前面的部分说明了如何将 Sequence
与 Column
关联为Python 端默认生成器:
Column(
"cart_id",
Integer,
Sequence("cart_id_seq", metadata=metadata_obj, start=1),
primary_key=True,
)
在上述情况下,当相关的 Table
被 CREATE / DROP 时,Sequence
将自动受到 CREATE SEQUENCE / DROP SEQUENCE DDL 的影响。但是,当发出 CREATE TABLE 时,该序列不会作为列的服务器端默认值存在。
如果我们希望序列被用作服务器端默认值,即使我们从 SQL 命令行向表中发出 INSERT 命令,我们可以使用 Column.server_default
参数与序列的值生成函数一起使用,该函数可以从 Sequence.next_value()
方法中获取。下面我们将演示相同的 Sequence
作为 Python 端默认生成器以及服务器端默认生成器与 Column
相关联的情况:
cart_id_seq = Sequence("cart_id_seq", metadata=metadata_obj, start=1)
table = Table(
"cartitems",
metadata_obj,
Column(
"cart_id",
Integer,
cart_id_seq,
server_default=cart_id_seq.next_value(),
primary_key=True,
),
Column("description", String(40)),
Column("createdate", DateTime()),
)
或者使用 ORM:
class CartItem(Base):
__tablename__ = "cartitems"
cart_id_seq = Sequence("cart_id_seq", metadata=Base.metadata, start=1)
cart_id = Column(
Integer, cart_id_seq, server_default=cart_id_seq.next_value(), primary_key=True
)
description = Column(String(40))
createdate = Column(DateTime)
当发出“CREATE TABLE”语句时,在 PostgreSQL 上,它将被生成为:
CREATE TABLE cartitems (
cart_id INTEGER DEFAULT nextval('cart_id_seq') NOT NULL,
description VARCHAR(40),
createdate TIMESTAMP WITHOUT TIME ZONE,
PRIMARY KEY (cart_id)
)
在 Python 端和服务器端默认生成上下文中放置 Sequence
确保“主键获取”逻辑在所有情况下都能正常工作。通常,启用序列的数据库还支持 INSERT 语句的 RETURNING,当发出此语句时,SQLAlchemy 会自动使用它。但是,如果对于特定的插入未使用 RETURNING,则 SQLAlchemy 更愿意在 INSERT 语句本身之外“预先执行”序列,只有在将序列作为 Python 端默认生成函数包含时才能正常工作。
该示例还将 Sequence
直接与封闭的 MetaData
关联起来,这再次确保 Sequence
完全与 MetaData
集合的参数相关联,包括默认模式(如果有)。
另请参阅
序列/SERIAL/IDENTITY - 在 PostgreSQL 方言文档中
返回支持 - 在 Oracle 方言文档中
将序列关联到 SERIAL 列
PostgreSQL 的 SERIAL 数据类型是一种自增类型,它意味着在发出 CREATE TABLE 时会隐式创建一个 PostgreSQL 序列。当为 Column
指定 Sequence
构造时,可以通过为 Sequence.optional
参数指定 True
值来表明在这种特定情况下不应使用它。这允许给定的 Sequence
用于没有其他替代主键生成系统的后端,但对于诸如 PostgreSQL 之类的后端,它会自动生成一个特定列的序列:
table = Table(
"cartitems",
metadata_obj,
Column(
"cart_id",
Integer,
# use an explicit Sequence where available, but not on
# PostgreSQL where SERIAL will be used
Sequence("cart_id_seq", start=1, optional=True),
primary_key=True,
),
Column("description", String(40)),
Column("createdate", DateTime()),
)
在上面的例子中,对于 PostgreSQL 的 CREATE TABLE
将使用 SERIAL
数据类型来创建 cart_id
列,而 cart_id_seq
序列将被忽略。然而,在 Oracle 中,cart_id_seq
序列将被显式创建。
提示
SERIAL 和 SEQUENCE 的这种特定交互相当古老,与其他情况一样,改用 Identity
将简化操作,只需在所有支持的后端上使用 IDENTITY
即可。
单独执行序列
SEQUENCE 是 SQL 中的一级模式对象,并且可以在数据库中独立生成值。如果你有一个 Sequence
对象,可以直接将其传递给 SQL 执行方法,通过其“next value”指令来调用它:
with my_engine.connect() as conn:
seq = Sequence("some_sequence", start=1)
nextid = conn.execute(seq)
为了将 Sequence
的“next value”函数嵌入到类似 SELECT 或 INSERT 的 SQL 语句中,可以使用 Sequence.next_value()
方法,该方法将在语句编译时生成适合目标后端的 SQL 函数:
>>> my_seq = Sequence("some_sequence", start=1)
>>> stmt = select(my_seq.next_value())
>>> print(stmt.compile(dialect=postgresql.dialect()))
SELECT nextval('some_sequence') AS next_value_1
将 Sequence 与 MetaData 关联起来
对于要与任意 Table
对象关联的 Sequence
,可以使用 Sequence.metadata
参数将 Sequence
关联到特定的 MetaData
:
seq = Sequence("my_general_seq", metadata=metadata_obj, start=1)
这样的序列可以按照通常的方式与列关联起来:
table = Table(
"cartitems",
metadata_obj,
seq,
Column("description", String(40)),
Column("createdate", DateTime()),
)
在上面的例子中,Sequence
对象被视为一个独立的模式构造,可以独立存在或在表之间共享。
显式地将 Sequence
与 MetaData
关联起来,可以实现以下行为:
-
Sequence
会继承指定给目标MetaData
的MetaData.schema
参数,这会影响 CREATE / DROP DDL 的生成,以及Sequence.next_value()
函数在 SQL 语句中的呈现方式。 -
MetaData.create_all()
和MetaData.drop_all()
方法将为此Sequence
发出 CREATE / DROP,即使该Sequence
未与此MetaData
的任何成员Table
/Column
关联。
将 Sequence 关联为服务器端默认
注意
以下技术仅在 PostgreSQL 数据库中可用。它在 Oracle 中不起作用。
前面的部分演示了如何将 Sequence
关联到 Column
作为Python 端默认生成器:
Column(
"cart_id",
Integer,
Sequence("cart_id_seq", metadata=metadata_obj, start=1),
primary_key=True,
)
在上述情况下,当相关的 Table
要被创建 / 删除时,Sequence
将自动受到 CREATE SEQUENCE / DROP SEQUENCE DDL 的影响。但是,在发出 CREATE TABLE 时,该序列不会出现为该列的服务器端默认。
如果我们希望序列被用作服务器端默认,即使我们从 SQL 命令行向表中发出 INSERT 命令,我们可以使用 Column.server_default
参数,与序列的值生成函数一起使用,该函数可以从 Sequence.next_value()
方法获得。下面我们演示了相同的 Sequence
同时关联到 Column
,既作为 Python 端的默认生成器,又作为服务器端的默认生成器:
cart_id_seq = Sequence("cart_id_seq", metadata=metadata_obj, start=1)
table = Table(
"cartitems",
metadata_obj,
Column(
"cart_id",
Integer,
cart_id_seq,
server_default=cart_id_seq.next_value(),
primary_key=True,
),
Column("description", String(40)),
Column("createdate", DateTime()),
)
或使用 ORM:
class CartItem(Base):
__tablename__ = "cartitems"
cart_id_seq = Sequence("cart_id_seq", metadata=Base.metadata, start=1)
cart_id = Column(
Integer, cart_id_seq, server_default=cart_id_seq.next_value(), primary_key=True
)
description = Column(String(40))
createdate = Column(DateTime)
在发出“CREATE TABLE”语句时,在 PostgreSQL 上会发出:
CREATE TABLE cartitems (
cart_id INTEGER DEFAULT nextval('cart_id_seq') NOT NULL,
description VARCHAR(40),
createdate TIMESTAMP WITHOUT TIME ZONE,
PRIMARY KEY (cart_id)
)
在 Python 端和服务器端默认生成上下文中放置Sequence
可以确保“主键提取”逻辑在所有情况下都有效。 通常,启用序列的数据库也支持对 INSERT 语句使用 RETURNING,当发出此语句时,SQLAlchemy 会自动使用它。 但是,如果对特定插入未使用 RETURNING,则 SQLAlchemy 更愿意在 INSERT 语句本身之外“预执行”序列,这仅在序列作为 Python 端默认生成器函数时有效。
该示例还将Sequence
直接与封闭的MetaData
关联起来,这再次确保了Sequence
与MetaData
集合的参数完全关联,包括默认模式(如果有)。
另请参阅
序列/SERIAL/IDENTITY - 在 PostgreSQL 方言文档中
RETURNING 支持 - 在 Oracle 方言文档中
计算列(GENERATED ALWAYS AS)
1.3.11 版中新增。
Computed
构造允许将 Column
声明为“GENERATED ALWAYS AS”列,在 DDL 中,即由数据库服务器计算值的列。 该构造接受一个 SQL 表达式,通常使用字符串或 text()
构造进行文本声明,类似于 CheckConstraint
的方式。 然后,数据库服务器会解释该 SQL 表达式,以确定行内列的值。
示例:
from sqlalchemy import Table, Column, MetaData, Integer, Computed
metadata_obj = MetaData()
square = Table(
"square",
metadata_obj,
Column("id", Integer, primary_key=True),
Column("side", Integer),
Column("area", Integer, Computed("side * side")),
Column("perimeter", Integer, Computed("4 * side")),
)
在 PostgreSQL 12 后端上运行 square
表的 DDL 如下所示:
CREATE TABLE square (
id SERIAL NOT NULL,
side INTEGER,
area INTEGER GENERATED ALWAYS AS (side * side) STORED,
perimeter INTEGER GENERATED ALWAYS AS (4 * side) STORED,
PRIMARY KEY (id)
)
值是在 INSERT 和 UPDATE 时持久化,还是在获取时计算,是数据库的实现细节;前者称为“存储”,后者称为“虚拟”。 一些数据库实现支持两者,但有些只支持其中一个。 可以指定可选的 Computed.persisted
标志为 True
或 False
,以指示是否在 DDL 中渲染“STORED”或“VIRTUAL”关键字,但是如果目标后端不支持该关键字,则会引发错误; 如果将其设置为未设置,则将使用目标后端的有效默认值。
计算列
构造是 FetchedValue
对象的子类,并且会自行设置为目标 列
的“服务器默认值”和“服务器更新时生成器”,这意味着当生成 INSERT 和 UPDATE 语句时,它将被视为默认生成的列,以及当使用 ORM 时,它将被视为生成的列被获取。这包括它将作为数据库的 RETURNING 子句的一部分,对于支持 RETURNING 并且生成的值需要被急切地获取的数据库。
注
使用 计算列
构造定义的 列
可能不会存储除服务器应用之外的任何值;当尝试写入 INSERT 或 UPDATE 时,SQLAlchemy 目前的行为是将忽略该值。
“GENERATED ALWAYS AS” 目前已知受支持的数据库有:
-
MySQL 版本 5.7 及以上
-
MariaDB 10.x 系列及以上
-
PostgreSQL 版本 12 及以上
-
Oracle - 注意 RETURNING 在 UPDATE 中无法正常工作(在包含计算列的 UPDATE..RETURNING 被呈现时会发出警告)
-
Microsoft SQL Server
-
SQLite 版本 3.31 及以上
当 计算列
与不受支持的后端一起使用时,如果目标方言不支持它,则在尝试呈现构造时会引发 CompileError
。否则,如果方言支持它但使用的特定数据库服务器版本不支持它,则在将 DDL 发送到数据库时会引发 DBAPIError
的子类,通常是 OperationalError
。
请参见
计算列
自增列(GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY)
1.4 版本中新增。
Identity
构造允许将 列
声明为自增列,并在 DDL 中呈现为“GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY”。自增列的值由数据库服务器自动生成,使用增量(或减量)序列。该构造与 Sequence
共享大部分用于控制数据库行为的选项。
示例:
from sqlalchemy import Table, Column, MetaData, Integer, Identity, String
metadata_obj = MetaData()
data = Table(
"data",
metadata_obj,
Column("id", Integer, Identity(start=42, cycle=True), primary_key=True),
Column("data", String),
)
在 PostgreSQL 12 后端上运行时,data
表的 DDL 如下所示:
CREATE TABLE data (
id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 42 CYCLE) NOT NULL,
data VARCHAR,
PRIMARY KEY (id)
)
数据库将在插入时为 id
列生成一个值,从 42
开始,如果语句尚未包含 id
列的值。身份列也可以要求数据库生成列的值,忽略语句中传递的值或者根据后端引发错误。要激活此模式,请在 Identity
构造函数中将参数 Identity.always
设置为 True
。将上一个示例更新以包含此参数将生成以下 DDL:
CREATE TABLE data (
id INTEGER GENERATED ALWAYS AS IDENTITY (START WITH 42 CYCLE) NOT NULL,
data VARCHAR,
PRIMARY KEY (id)
)
Identity
构造函数是 FetchedValue
对象的子类,并将自己设置为目标 Column
的“服务器默认”生成器,这意味着当生成 INSERT 语句时,它将被视为默认生成列,以及在使用 ORM 时,它将被视为生成列。这包括它将作为数据库的 RETURNING 子句的一部分,对于支持 RETURNING 并且要急切获取生成的值的数据库来说,它将被提前获取。
当前已知支持 Identity
构造函数的包括:
-
PostgreSQL 版本为 10。
-
Oracle 版本为 12. 还支持传递
always=None
以启用默认生成模式,以及传递参数on_null=True
以指定“ON NULL”与“BY DEFAULT”身份列一起使用。 -
Microsoft SQL Server. MSSQL 使用一种自定义语法,仅支持
start
和increment
参数,而忽略所有其他参数。
当 Identity
与不受支持的后端一起使用时,它会被忽略,并且会使用默认的 SQLAlchemy 自增列逻辑。
当 Column
同时指定 Identity
并将 Column.autoincrement
设置为 False
时,将引发错误。
另请参阅
Identity
默认对象 API
对象名称 | 描述 |
---|---|
ColumnDefault | 列的普通默认值。 |
Computed | 定义了一个生成的列,即“GENERATED ALWAYS AS”语法。 |
DefaultClause | 由 DDL 指定的 DEFAULT 列值。 |
DefaultGenerator | 用于列默认值的基类。 |
FetchedValue | 透明数据库端默认值的标记。 |
Identity | 定义标识列,即“GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY”语法。 |
Sequence | 表示命名的数据库序列。 |
class sqlalchemy.schema.Computed
定义一个生成列,即“GENERATED ALWAYS AS”语法。
Computed
构造是添加到Column
对象的参数列表中的内联构造:
from sqlalchemy import Computed
Table('square', metadata_obj,
Column('side', Float, nullable=False),
Column('area', Float, Computed('side * side'))
)
请参阅下面链接的文档以获取完整详细信息。
版本 1.3.11 中的新功能。
另请参阅
计算列(GENERATED ALWAYS AS)
成员
init(), copy()
类签名
类sqlalchemy.schema.Computed
(sqlalchemy.schema.FetchedValue
,sqlalchemy.schema.SchemaItem
)
method __init__(sqltext: _DDLColumnArgument, persisted: bool | None = None) → None
构造一个生成的 DDL 构造,以配合Column
。
参数:
-
sqltext
–包含列生成表达式的字符串,该表达式将逐字使用,或者 SQL 表达式构造,例如
text()
对象。 如果以字符串形式给出,则将对象转换为text()
对象。警告
Computed.sqltext
参数可以作为 Python 字符串参数传递给Computed
,它将被视为受信任的 SQL 文本并按照给定的方式呈现。 不要将不受信任的输入传递给此参数。 -
persisted
–可选,控制数据库如何持久化此列。 可能的值为:
-
None
,默认值,将使用数据库定义的默认持久性。 -
True
,将呈现GENERATED ALWAYS AS ... STORED
,或者如果支持的话,将呈现目标数据库的等效值。 -
False
,将呈现GENERATED ALWAYS AS ... VIRTUAL
,或者如果支持的话,将呈现目标数据库的等效值。
当 DDL 发出到目标数据库时,如果数据库不支持持久性选项,则指定
True
或False
可能会引发错误。 将此参数保留在其默认值None
上可确保对所有支持GENERATED ALWAYS AS
的数据库都能成功。 -
method copy(*, target_table: Table | None = None, **kw: Any) → Computed
自版本 1.4 起已弃用:Computed.copy()
方法已弃用,并将在将来的版本中删除。
class sqlalchemy.schema.ColumnDefault
列上的普通默认值。
这可能对应于一个常量,一个可调用函数,或者一个 SQL 子句。
每当使用 Column
的 default
、onupdate
参数时,都会自动生成 ColumnDefault
。ColumnDefault
也可以按位置传递。
例如,以下内容:
Column('foo', Integer, default=50)
等同于:
Column('foo', Integer, ColumnDefault(50))
类签名
class sqlalchemy.schema.ColumnDefault
(sqlalchemy.schema.DefaultGenerator
, abc.ABC
)
class sqlalchemy.schema.DefaultClause
由 DDL 指定的 DEFAULT 列值。
DefaultClause
是一个 FetchedValue
,在发出“CREATE TABLE”时也会生成一个“DEFAULT”子句。
每当使用 Column
的 server_default
、server_onupdate
参数时,都会自动生成 DefaultClause
。DefaultClause
也可以按位置传递。
例如,以下内容:
Column('foo', Integer, server_default="50")
等同于:
Column('foo', Integer, DefaultClause("50"))
类签名
class sqlalchemy.schema.DefaultClause
(sqlalchemy.schema.FetchedValue
)
class sqlalchemy.schema.DefaultGenerator
列默认值的基类。
此对象仅存在于 column.default 或 column.onupdate。它不作为服务器默认值有效。
类签名
class sqlalchemy.schema.DefaultGenerator
(sqlalchemy.sql.expression.Executable
, sqlalchemy.schema.SchemaItem
)
class sqlalchemy.schema.FetchedValue
一个用于透明数据库端默认值的标记。
当数据库配置为为列提供一些自动默认值时,请使用 FetchedValue
。
例如:
Column('foo', Integer, FetchedValue())
将指示某个触发器或默认生成器在插入期间为 foo
列创建一个新值。
另请参阅
标记隐式生成的值、时间戳和触发列
类签名
class sqlalchemy.schema.FetchedValue
(sqlalchemy.sql.expression.SchemaEventTarget
)
class sqlalchemy.schema.Sequence
表示一个命名的数据库序列。
Sequence
对象表示数据库序列的名称和配置参数。它还表示可以由 SQLAlchemy Engine
或 Connection
“执行”的构造,为目标数据库渲染适当的 “下一个值” 函数并返回结果。
Sequence
通常与主键列相关联:
some_table = Table(
'some_table', metadata,
Column('id', Integer, Sequence('some_table_seq', start=1),
primary_key=True)
)
当为上述 Table
发出 CREATE TABLE 时,如果目标平台支持序列,则还将发出 CREATE SEQUENCE 语句。对于不支持序列的平台,将忽略 Sequence
构造。
另请参阅
定义序列
CreateSequence
DropSequence
成员
init(), create(), drop(), next_value()
类签名
类 sqlalchemy.schema.Sequence
(sqlalchemy.schema.HasSchemaAttr
, sqlalchemy.schema.IdentityOptions
, sqlalchemy.schema.DefaultGenerator
)
method __init__(name: str, start: int | None = None, increment: int | None = None, minvalue: int | None = None, maxvalue: int | None = None, nominvalue: bool | None = None, nomaxvalue: bool | None = None, cycle: bool | None = None, schema: str | Literal[SchemaConst.BLANK_SCHEMA] | None = None, cache: int | None = None, order: bool | None = None, data_type: _TypeEngineArgument[int] | None = None, optional: bool = False, quote: bool | None = None, metadata: MetaData | None = None, quote_schema: bool | None = None, for_update: bool = False) → None
构造一个 Sequence
对象。
参数:
-
name
– 序列的名称。 -
start
–序列的起始索引。当向数据库发出 CREATE SEQUENCE 命令时,此值用作 “START WITH” 子句的值。如果为
None
,则省略子句,大多数平台上表示起始值为 1。从版本 2.0 开始:要使 DDL 发出 “START WITH” 命令,
Sequence.start
参数是必需的。这是对版本 1.4 中所做更改的逆转,该更改如果未包括Sequence.start
将隐式地渲染 “START WITH 1”。有关更多详细信息,请参见序列构造将恢复为没有任何显式默认的“start”值;影响 MS SQL Server。 -
increment
– 序列的增量值。当向数据库发出 CREATE SEQUENCE 命令时,此值用作 “INCREMENT BY” 子句的值。如果为None
,则省略子句,大多数平台上表示增量为 1。 -
minvalue
– 序列的最小值。当将 CREATE SEQUENCE 命令发送到数据库时,此值用作“MINVALUE”子句的值。如果为None
,则省略该子句,在大多数平台上表示升序和降序序列的最小值分别为 1 和-2⁶³-1。 -
maxvalue
– 序列的最大值。当将 CREATE SEQUENCE 命令发送到数据库时,此值用作“MAXVALUE”子句的值。如果为None
,则省略该子句,在大多数平台上表示升序和降序序列的最大值分别为 2⁶³-1 和-1。 -
nominvalue
– 序列的无最小值。当将 CREATE SEQUENCE 命令发送到数据库时,此值用作“NO MINVALUE”子句的值。如果为None
,则省略该子句,在大多数平台上表示升序和降序序列的最小值分别为 1 和-2⁶³-1。 -
nomaxvalue
– 序列的无最大值。当将 CREATE SEQUENCE 命令发送到数据库时,此值用作“NO MAXVALUE”子句的值。如果为None
,则省略该子句,在大多数平台上表示升序和降序序列的最大值分别为 2⁶³-1 和-1。 -
cycle
– 允许序列在达到最大值或最小值时循环。当升序或降序序列分别达到最大值或最小值时,此值用于在将 CREATE SEQUENCE 命令发送到数据库时作为“CYCLE”子句。如果达到限制,则生成的下一个数字将分别是最小值或最大值。如果 cycle=False(默认值),则在序列达到其最大值后调用 nextval 将返回错误。 -
schema
– 序列的可选模式名称,如果位于除默认模式之外的模式中。当MetaData
也存在时,选择模式名称的规则与Table.schema
的规则相同。 -
cache
– 可选的整数值;提前计算序列中未来值的数量。渲染 Oracle 和 PostgreSQL 理解的 CACHE 关键字。 -
order
– 可选的布尔值;如果为True
,则渲染 ORDER 关键字,Oracle 可理解此关键字,表示序列是有确定顺序的。可能需要使用 Oracle RAC 提供确定性排序。 -
data_type
–序列要返回的类型,对于允许我们在 INTEGER、BIGINT 等之间选择的方言(例如 mssql)。
自 1.4.0 版本新增。
-
optional
– 布尔值,当为True
时,表示这个Sequence
对象只需在不提供其他方法生成主键标识符的后端上显式生成。目前,它基本上意味着“在 PostgreSQL 后端上不要创建这个序列,在那里,SERIAL 关键字会自动为我们创建一个序列”。 -
quote
– 布尔值,当为True
或False
时,显式地强制对Sequence.name
进行引用或取消引用。当保持其默认值None
时,将根据大小写和保留字规则进行正常的引用。 -
quote_schema
– 设置对schema
名称的引用偏好。 -
metadata
–可选的
MetaData
对象,这个Sequence
将与之关联。与MetaData
关联的Sequence
将获得以下功能:-
Sequence
将继承指定给目标MetaData
的MetaData.schema
参数,这会影响创建/删除 DDL 的生成,如果有的话。 -
Sequence.create()
和Sequence.drop()
方法会自动使用绑定到MetaData
对象的引擎(如果有的话)。 -
MetaData.create_all()
和MetaData.drop_all()
方法将为这个Sequence
发出 CREATE / DROP,即使这个Sequence
没有与任何属于这个MetaData
的Table
/Column
相关联也是如此。
上述行为只有在通过此参数将
Sequence
显式关联到MetaData
时才会发生。另请参见
将 Sequence 与 MetaData 关联 - 对
Sequence.metadata
参数的完整讨论。 -
-
for_update
– 当与Column
相关联时,表示应该在该列的表上对 UPDATE 语句调用此Sequence
,而不是在 INSERT 语句中,当该列在语句中没有其他值时。
method create(bind: _CreateDropBind, checkfirst: bool = True) → None
在数据库中创建此序列。
method drop(bind: _CreateDropBind, checkfirst: bool = True) → None
从数据库中删除此序列。
method next_value() → Function[int]
返回一个next_value
函数元素,该函数将在任何 SQL 表达式中为此Sequence
呈现适当的增量函数。
class sqlalchemy.schema.Identity
定义一个 identity 列,即“GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY”语法。
Identity
构造是一个内联构造,添加到Column
对象的参数列表中:
from sqlalchemy import Identity
Table('foo', metadata_obj,
Column('id', Integer, Identity())
Column('description', Text),
)
详细信息请参见下面的链接文档。
版本 1.4 中新增。
另请参阅
Identity 列(GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY)
成员
init(), copy()
类签名
class sqlalchemy.schema.Identity
(sqlalchemy.schema.IdentityOptions
, sqlalchemy.schema.FetchedValue
, sqlalchemy.schema.SchemaItem
)
method __init__(always: bool = False, on_null: bool | None = None, start: int | None = None, increment: int | None = None, minvalue: int | None = None, maxvalue: int | None = None, nominvalue: bool | None = None, nomaxvalue: bool | None = None, cycle: bool | None = None, cache: int | None = None, order: bool | None = None) → None
构造一个 GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY 的 DDL 构造,以配合一个Column
。
有关大多数参数的完整描述,请参阅Sequence
文档。
注意
MSSQL 支持此构造作为在列上生成 IDENTITY 的首选替代方法,但它使用的非标准语法仅支持Identity.start
和Identity.increment
。所有其他参数都将被忽略。
参数:
-
always
– 一个布尔值,表示身份列的类型。如果指定为False
,则用户指定的值优先。如果指定为True
,则不接受用户指定的值(在某些后端,如 PostgreSQL,可以在 INSERT 中指定 OVERRIDING SYSTEM VALUE 或类似的内容来覆盖序列值)。一些后端也对此参数有一个默认值,None
可以用来省略在 DDL 中呈现这部分。如果后端没有默认值,则将其视为False
。 -
on_null
– 设置为True
以指定在always=False
身份列中与ON NULL
一起使用。此选项仅在某些后端(如 Oracle)上受支持。 -
start
– 序列的起始索引。 -
increment
– 序列的增量值。 -
minvalue
– 序列的最小值。 -
maxvalue
– 序列的最大值。 -
nominvalue
– 序列没有最小值。 -
nomaxvalue
– 序列没有最大值。 -
cycle
– 允许序列在达到maxvalue
或minvalue
时循环。 -
cache
– 可选整数值;提前计算的序列中未来值的数量。 -
order
– 可选布尔值;如果为真,则呈现 ORDER 关键字。
method copy(**kw: Any) → Identity
自版本 1.4 弃用:Identity.copy()
方法已弃用,并将在将来的版本中移除。