反射数据库对象

一个 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 表的信息,然后生成 ColumnForeignKey 以及其他与该信息相对应的对象,就好像 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。这样,如果表属性尚未加载,则会加载它们。autoload 操作仅在表尚未加载时发生;一旦加载,对 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 是一个 Table 对象,它包含 Column 对象,表示视图“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 对象的默认模式,使用 MetaData.schema 参数。

直接使用此模式参数会影响表格反射功能在被要求反射对象时所查找的位置。例如,给定一个使用其 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 中,是 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”中的行,这意味着有一个 ForeignKeyConstraint 对象是“messages”表定义的一部分。

我们可能会发现自己处于一个情况,其中一个 MetaData 集合可能包含多达四个 Table 对象,它们代表这两个数据库表,其中一个或两个附加表是由反射过程生成的;这是因为当反射过程在被反射的表上遇到外部键约束时,它会分支出来也反射该引用的表。它用于为该引用表分配模式的决策是,SQLAlchemy 将省略从反射的 ForeignKeyConstraint 对象中省略默认模式,如果拥有 Table 也省略了它的模式名称,并且这两个对象在同一个模式中,但如果它没有被省略,则包含它。

常见的情况是,当以带模式限定的方式反射表时,然后加载相关表,该操作也以带模式限定的方式执行

>>> # 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 search_path - 关于此行为在 PostgreSQL 数据库中的更多细节。

使用 Inspector 进行细粒度反射

还提供了一个低级接口,该接口提供了一个与后端无关的系统,用于从给定数据库中加载模式、表、列和约束描述的列表。这被称为“Inspector”

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 的反射方法的代理,提供一致的接口以及对先前获取的元数据的缓存支持。

通常通过 inspect() 函数创建 Inspector 对象,该函数可以传递 EngineConnection

from sqlalchemy import inspect, create_engine
engine = create_engine('...')
insp = inspect(engine)

在上面,与引擎关联的 Dialect 可以选择返回 Inspector 子类,该子类提供特定于方言目标数据库的附加方法。

类签名

class sqlalchemy.engine.reflection.Inspector (sqlalchemy.inspection.Inspectable)

method sqlalchemy.engine.reflection.Inspector.__init__(bind: Engine | Connection)

初始化一个新的 Inspector

Deprecated since version 1.4: Inspector 上的 __init__() 方法已弃用,将在未来版本中删除。请在 EngineConnection 上使用 inspect() 函数来获取 Inspector

参数::

bind – 一个 Connection,通常是 EngineConnection 的实例。

有关 Inspector 的方言特定实例,请参阅 Inspector.from_engine()

attribute sqlalchemy.engine.reflection.Inspector.bind: Engine | Connection
method sqlalchemy.engine.reflection.Inspector.clear_cache() None

重置此 Inspector 的缓存。

具有缓存数据的检查方法将在下次调用时发出 SQL 查询以获取新数据。

新版 2.0 新增。

attribute sqlalchemy.engine.reflection.Inspector.default_schema_name

返回当前引擎数据库用户的方言呈现的默认模式名称。

例如,对于 PostgreSQL 通常为 public,对于 SQL Server 通常为 dbo

attribute sqlalchemy.engine.reflection.Inspector.dialect: Dialect
attribute sqlalchemy.engine.reflection.Inspector.engine: Engine
classmethod sqlalchemy.engine.reflection.Inspector.from_engine(bind: Engine) Inspector

从给定的引擎或连接构造一个新的特定于方言的 Inspector 对象。

自版本 1.4 起已弃用: Inspector 上的 from_engine() 方法已弃用,将在未来版本中删除。 请使用 inspect() 函数在 EngineConnection 上获取 Inspector

参数::

bindConnectionEngine

此方法不同于 Inspector 的直接构造函数调用,因为 Dialect 有机会提供特定于方言的 Inspector 实例,该实例可能提供其他方法。

请参阅 Inspector 中的示例。

method sqlalchemy.engine.reflection.Inspector.get_check_constraints(table_name: str, schema: str | None = None, **kw: Any) List[ReflectedCheckConstraint]

返回有关 table_name 中检查约束的信息。

给定一个字符串 table_name 和一个可选的字符串 schema,返回检查约束信息,作为 ReflectedCheckConstraint 列表。

参数::
  • table_name – 表的字符串名称。 对于特殊引用,请使用 quoted_name

  • schema – 字符串模式名称; 如果省略,则使用数据库连接的默认模式。 对于特殊引用,请使用 quoted_name

  • **kw – 要传递给特定于方言的实现的额外关键字参数。 有关更多信息,请参阅所用方言的文档。

返回值:

字典列表,每个字典代表一个检查约束的定义。

method sqlalchemy.engine.reflection.Inspector.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 – 传递给特定于方言的实现的其他关键字参数。 有关更多信息,请参阅所用方言的文档。

返回值:

字典列表,每个字典都代表数据库列的定义。

method sqlalchemy.engine.reflection.Inspector.get_foreign_keys(table_name: str, schema: str | None = None, **kw: Any) List[ReflectedForeignKeyConstraint]

返回有关 table_name 中外键的信息。

给定字符串 table_name 和可选字符串 schema,以 ReflectedForeignKeyConstraint 列表的形式返回外键信息。

参数::
  • table_name – 表的字符串名称。 对于特殊引用,请使用 quoted_name.

  • schema – 字符串模式名称;如果省略,则使用数据库连接的默认模式。 对于特殊引用,请使用 quoted_name.

  • **kw – 传递给特定于方言的实现的其他关键字参数。 有关更多信息,请参阅所用方言的文档。

返回值:

字典列表,每个字典都代表外键定义。

method sqlalchemy.engine.reflection.Inspector.get_indexes(table_name: str, schema: str | None = None, **kw: Any) List[ReflectedIndex]

返回有关 table_name 中索引的信息。

给定字符串 table_name 和可选字符串 schema,以 ReflectedIndex 列表的形式返回索引信息。

参数::
  • table_name – 表的字符串名称。 对于特殊引用,请使用 quoted_name.

  • schema – 字符串模式名称;如果省略,则使用数据库连接的默认模式。 对于特殊引用,请使用 quoted_name.

  • **kw – 传递给特定于方言的实现的其他关键字参数。 有关更多信息,请参阅所用方言的文档。

返回值:

字典列表,每个字典都代表索引的定义。

method sqlalchemy.engine.reflection.Inspector.get_materialized_view_names(schema: str | None = None, **kw: Any) List[str]

返回 schema 中所有物化视图名称。

参数::
  • schema – 可选,从非默认模式检索名称。 对于特殊引用,请使用 quoted_name.

  • **kw – 传递给特定于方言的实现的其他关键字参数。 有关更多信息,请参阅所用方言的文档。

新版 2.0 新增。

method sqlalchemy.engine.reflection.Inspector.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 新增。

method sqlalchemy.engine.reflection.Inspector.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 新增。

method sqlalchemy.engine.reflection.Inspector.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 新增。

method sqlalchemy.engine.reflection.Inspector.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 新增。

method sqlalchemy.engine.reflection.Inspector.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 新增。

method sqlalchemy.engine.reflection.Inspector.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 新增。

method sqlalchemy.engine.reflection.Inspector.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 新增。

method sqlalchemy.engine.reflection.Inspector.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 新增。

method sqlalchemy.engine.reflection.Inspector.get_pk_constraint(table_name: str, schema: str | None = None, **kw: Any) ReflectedPrimaryKeyConstraint

返回有关 table_name 中主键约束的信息。

给定一个字符串 table_name 和一个可选的字符串 schema,返回主键信息作为 ReflectedPrimaryKeyConstraint

参数::
  • table_name – 表的字符串名称。对于特殊引用,请使用 quoted_name

  • schema – 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用 quoted_name

  • **kw – 传递给特定方言实现的其他关键字参数。有关更多信息,请参阅所用方言的文档。

返回值:

一个字典,表示主键约束的定义。

method sqlalchemy.engine.reflection.Inspector.get_schema_names(**kw: Any) List[str]

返回所有模式名称。

参数::

**kw – 传递给特定方言实现的其他关键字参数。有关更多信息,请参阅所用方言的文档。

method sqlalchemy.engine.reflection.Inspector.get_sequence_names(schema: str | None = None, **kw: Any) List[str]

返回 schema 中的所有序列名称。

参数::
  • schema – 可选,从非默认模式中检索名称。对于特殊引用,请使用 quoted_name

  • **kw – 传递给特定方言实现的其他关键字参数。有关更多信息,请参阅所用方言的文档。

method sqlalchemy.engine.reflection.Inspector.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), ..]),其中包含剩余的外键约束名,这些约束名需要在创建之后单独创建,这基于表之间的依赖关系。

参数::
  • schema – 要查询的模式名,如果它不是默认模式。

  • **kw – 传递给特定方言实现的其他关键字参数。有关更多信息,请参阅所用方言的文档。

另请参阅

Inspector.get_table_names()

sort_tables_and_constraints() - 类似的方法,它使用已经给定的 MetaData

method sqlalchemy.engine.reflection.Inspector.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 中的新增功能。

method sqlalchemy.engine.reflection.Inspector.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 – 传递给方言特定实现的附加关键字参数。 有关更多信息,请参阅所用方言的文档。

method sqlalchemy.engine.reflection.Inspector.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 – 传递给方言特定实现的附加关键字参数。 有关更多信息,请参阅所用方言的文档。

返回值:

包含表选项的字典。 返回的键取决于所用方言。 每个键都以方言名称为前缀。

method sqlalchemy.engine.reflection.Inspector.get_temp_table_names(**kw: Any) List[str]

返回当前绑定的临时表名称列表。

此方法不受大多数方言的支持; 目前只有 Oracle、PostgreSQL 和 SQLite 实现了它。

参数::

**kw – 传递给方言特定实现的附加关键字参数。 有关更多信息,请参阅所用方言的文档。

method sqlalchemy.engine.reflection.Inspector.get_temp_view_names(**kw: Any) List[str]

返回当前绑定的临时视图名称列表。

此方法不受大多数方言的支持; 目前只有 PostgreSQL 和 SQLite 实现了它。

参数::

**kw – 传递给方言特定实现的附加关键字参数。 有关更多信息,请参阅所用方言的文档。

method sqlalchemy.engine.reflection.Inspector.get_unique_constraints(table_name: str, schema: str | None = None, **kw: Any) List[ReflectedUniqueConstraint]

返回有关 table_name 中唯一约束的信息。

给定一个字符串 table_name 和一个可选的字符串 schema,返回唯一约束信息作为 ReflectedUniqueConstraint 的列表。

参数::
  • table_name – 表的字符串名称。对于特殊引用,请使用 quoted_name

  • schema – 字符串模式名称;如果省略,则使用数据库连接的默认模式。对于特殊引用,请使用 quoted_name

  • **kw – 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅所用方言的文档。

返回值:

一个字典列表,每个字典代表唯一约束的定义。

method sqlalchemy.engine.reflection.Inspector.get_view_definition(view_name: str, schema: str | None = None, **kw: Any) str

返回名为 view_name 的普通视图或物化视图的定义。

参数::
  • view_name – 视图的名称。

  • schema – 可选,从非默认模式检索名称。对于特殊引用,请使用 quoted_name

  • **kw – 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅所用方言的文档。

method sqlalchemy.engine.reflection.Inspector.get_view_names(schema: str | None = None, **kw: Any) List[str]

返回 schema 中所有非物化视图的名称。

参数::
  • schema – 可选,从非默认模式检索名称。对于特殊引用,请使用 quoted_name

  • **kw – 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅所用方言的文档。

Changed in version 2.0: 对于以前在该列表中包含物化视图名称的那些方言(目前是 PostgreSQL),该方法不再返回物化视图的名称。应改为使用 Inspector.get_materialized_view_names() 方法。

method sqlalchemy.engine.reflection.Inspector.has_index(table_name: str, index_name: str, schema: str | None = None, **kw: Any) bool

检查数据库中是否存在特定索引名称。

参数::
  • table_name – 索引所属表的名称

  • index_name – 要检查的索引的名称

  • schema – 要查询的模式名称,如果不是默认模式。

  • **kw – 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅所用方言的文档。

新版 2.0 新增。

method sqlalchemy.engine.reflection.Inspector.has_schema(schema_name: str, **kw: Any) bool

如果后端具有给定名称的模式,则返回 True。

参数::
  • schema_name – 要检查的模式名称

  • **kw – 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅所用方言的文档。

新版 2.0 新增。

method sqlalchemy.engine.reflection.Inspector.has_sequence(sequence_name: str, schema: str | None = None, **kw: Any) bool

如果后端具有给定名称的序列,则返回 True。

参数::
  • sequence_name – 要检查的序列的名称

  • schema – 要查询的模式名称,如果不是默认模式。

  • **kw – 传递给特定方言实现的额外关键字参数。有关更多信息,请参阅所用方言的文档。

New in version 1.4.

method sqlalchemy.engine.reflection.Inspector.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 sqlalchemy.engine.reflection.Inspector.info_cache: Dict[Any, Any]
method sqlalchemy.engine.reflection.Inspector.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 sqlalchemy.engine.reflection.Inspector.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 对象相对应的反射元素的字典。

The ReflectedColumn structure is returned by the get_columns method.

类签名

class sqlalchemy.engine.interfaces.ReflectedColumn (builtins.dict)

attribute sqlalchemy.engine.interfaces.ReflectedColumn.autoincrement: NotRequired[bool]

数据库相关的自动递增标志。

此标志指示该列是否具有某种数据库端的“自动递增”标志。在 SQLAlchemy 中,其他类型的列也可能充当“自动递增”列,而无需在它们上设置此类标志。

有关“自动递增”的更多背景信息,请参阅 Column.autoincrement

attribute sqlalchemy.engine.interfaces.ReflectedColumn.comment: NotRequired[str | None]

如果存在,则为该列的注释。只有某些方言会返回此键。

attribute sqlalchemy.engine.interfaces.ReflectedColumn.computed: NotRequired[ReflectedComputed]

表示该列由数据库计算。只有某些方言会返回此键。

版本 1.3.16 中的新功能: - 添加了对计算反射的支持。

attribute sqlalchemy.engine.interfaces.ReflectedColumn.default: str | None

列默认表达式作为 SQL 字符串

attribute sqlalchemy.engine.interfaces.ReflectedColumn.dialect_options: NotRequired[Dict[str, Any]]

为该反射对象检测到的其他方言特定选项。

attribute sqlalchemy.engine.interfaces.ReflectedColumn.identity: NotRequired[ReflectedIdentity]

表示此列是 IDENTITY 列。只有某些方言会返回此键。

版本 1.4 中的新功能: - 添加了对 identity 列反射的支持。

attribute sqlalchemy.engine.interfaces.ReflectedColumn.name: str

列名

attribute sqlalchemy.engine.interfaces.ReflectedColumn.nullable: bool

如果该列是 NULL 还是 NOT NULL,则为布尔标志。

attribute sqlalchemy.engine.interfaces.ReflectedColumn.type: TypeEngine[Any]

列类型,表示为 TypeEngine 实例。

class sqlalchemy.engine.interfaces.ReflectedComputed

表示计算列的反射元素,对应于 Computed 结构。

The ReflectedComputed 结构是 ReflectedColumn 结构的一部分,该结构由 Inspector.get_columns() 方法返回。

成员

persisted, sqltext

类签名

class sqlalchemy.engine.interfaces.ReflectedComputed (builtins.dict)

attribute sqlalchemy.engine.interfaces.ReflectedComputed.persisted: NotRequired[bool]

表示值是存储在表中还是按需计算的

attribute sqlalchemy.engine.interfaces.ReflectedComputed.sqltext: str

用于生成此列的表达式,作为字符串 SQL 表达式返回

class sqlalchemy.engine.interfaces.ReflectedCheckConstraint

字典,表示对应于 CheckConstraint 的反射元素。

The ReflectedCheckConstraint 结构由 Inspector.get_check_constraints() 方法返回。

attribute sqlalchemy.engine.interfaces.ReflectedCheckConstraint.dialect_options: NotRequired[Dict[str, Any]]

为该检查约束检测到的其他方言特定选项。

版本 1.3.8 中的新功能。

attribute sqlalchemy.engine.interfaces.ReflectedCheckConstraint.sqltext: str

检查约束的 SQL 表达式

class sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint

表示与 ForeignKeyConstraint 相对应的反射元素的字典。

The ReflectedForeignKeyConstraint 结构由 Inspector.get_foreign_keys() 方法返回。

attribute sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint.constrained_columns: List[str]

构成外键的本地列名称

attribute sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint.options: NotRequired[Dict[str, Any]]

检测到此外键约束的附加选项

attribute sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint.referred_columns: List[str]

对应于constrained_columns 的引用列名称

attribute sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint.referred_schema: str | None

被引用表的模式名称

attribute sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint.referred_table: str

被引用表的名称

class sqlalchemy.engine.interfaces.ReflectedIdentity

表示列的反射 IDENTITY 结构,对应于 Identity 结构。

The ReflectedIdentity 结构是 ReflectedColumn 结构的一部分,该结构由 Inspector.get_columns() 方法返回。

类签名

class sqlalchemy.engine.interfaces.ReflectedIdentity (builtins.dict)

attribute sqlalchemy.engine.interfaces.ReflectedIdentity.always: bool

身份列类型

attribute sqlalchemy.engine.interfaces.ReflectedIdentity.cache: int | None

序列中预先计算的未来值的数量。

attribute sqlalchemy.engine.interfaces.ReflectedIdentity.cycle: bool

允许序列在达到 maxvalue 或 minvalue 后循环。

attribute sqlalchemy.engine.interfaces.ReflectedIdentity.increment: int

序列的增量值

attribute sqlalchemy.engine.interfaces.ReflectedIdentity.maxvalue: int

序列的最大值。

attribute sqlalchemy.engine.interfaces.ReflectedIdentity.minvalue: int

序列的最小值。

attribute sqlalchemy.engine.interfaces.ReflectedIdentity.nomaxvalue: bool

序列没有最大值。

attribute sqlalchemy.engine.interfaces.ReflectedIdentity.nominvalue: bool

序列没有最小值。

attribute sqlalchemy.engine.interfaces.ReflectedIdentity.on_null: bool

表示 ON NULL

attribute sqlalchemy.engine.interfaces.ReflectedIdentity.order: bool

如果为 true,则呈现 ORDER 关键字。

attribute sqlalchemy.engine.interfaces.ReflectedIdentity.start: int

序列的起始索引

class sqlalchemy.engine.interfaces.ReflectedIndex

表示与 Index 相对应的反射元素的字典。

Inspector.get_indexes() 方法返回的 ReflectedIndex 结构。

类签名

class sqlalchemy.engine.interfaces.ReflectedIndex (builtins.dict)

attribute sqlalchemy.engine.interfaces.ReflectedIndex.column_names: List[str | None]

索引引用的列名。如果该列表的元素是表达式,则为 None,并在 expressions 列表中返回。

attribute sqlalchemy.engine.interfaces.ReflectedIndex.column_sorting: NotRequired[Dict[str, Tuple[str]]]

可选的字典,将列名或表达式映射到排序关键字元组,这些关键字可能包括 ascdescnulls_firstnulls_last

版本 1.3.5 中的新增功能。

attribute sqlalchemy.engine.interfaces.ReflectedIndex.dialect_options: NotRequired[Dict[str, Any]]

此索引检测到的其他特定于方言的选项

attribute sqlalchemy.engine.interfaces.ReflectedIndex.duplicates_constraint: NotRequired[str | None]

指示此索引是否反映具有此名称的约束。

attribute sqlalchemy.engine.interfaces.ReflectedIndex.expressions: NotRequired[List[str]]

构成索引的表达式。当存在时,此列表同时包含普通列名(也存在于 column_names 中)和表达式(在 column_names 中为 None)。

attribute sqlalchemy.engine.interfaces.ReflectedIndex.include_columns: NotRequired[List[str]]

要包含在支持数据库的 INCLUDE 子句中的列。

版本 2.0 中弃用: 旧值,将被 index_dict["dialect_options"]["<dialect name>_include"] 替换

attribute sqlalchemy.engine.interfaces.ReflectedIndex.name: str | None

索引名称

attribute sqlalchemy.engine.interfaces.ReflectedIndex.unique: bool

索引是否具有唯一标志

class sqlalchemy.engine.interfaces.ReflectedPrimaryKeyConstraint

表示与 PrimaryKeyConstraint 相对应的反射元素的字典。

Inspector.get_pk_constraint() 方法返回的 ReflectedPrimaryKeyConstraint 结构。

attribute sqlalchemy.engine.interfaces.ReflectedPrimaryKeyConstraint.constrained_columns: List[str]

构成主键的列名

attribute sqlalchemy.engine.interfaces.ReflectedPrimaryKeyConstraint.dialect_options: NotRequired[Dict[str, Any]]

此主键检测到的其他特定于方言的选项

class sqlalchemy.engine.interfaces.ReflectedUniqueConstraint

表示与 UniqueConstraint 相对应的反射元素的字典。

ReflectedUniqueConstraint 结构返回,通过 Inspector.get_unique_constraints() 方法获得。

attribute sqlalchemy.engine.interfaces.ReflectedUniqueConstraint.column_names: List[str]

构成唯一约束的列名

attribute sqlalchemy.engine.interfaces.ReflectedUniqueConstraint.dialect_options: NotRequired[Dict[str, Any]]

此唯一约束检测到的其他特定于方言的选项

attribute sqlalchemy.engine.interfaces.ReflectedUniqueConstraint.duplicates_index: NotRequired[str | None]

指示此唯一约束是否复制了具有此名称的索引

class sqlalchemy.engine.interfaces.ReflectedTableComment

表示与 Table.comment 属性相对应的反射注释的字典。

ReflectedTableComment 结构返回,通过 Inspector.get_table_comment() 方法获得。

成员

text

类签名

class sqlalchemy.engine.interfaces.ReflectedTableComment (builtins.dict)

attribute sqlalchemy.engine.interfaces.ReflectedTableComment.text: str | None

注释的文本

使用数据库无关类型进行反射

当使用 Table.autoload_with 参数(Table)或 Inspector.get_columns() 方法(Inspector)反射表的列时,数据类型将尽可能具体到目标数据库。这意味着如果从 MySQL 数据库中反射一个“integer”数据类型,该类型将由 sqlalchemy.dialects.mysql.INTEGER 类表示,其中包含 MySQL 特定的属性,例如“display_width”。或者在 PostgreSQL 上,可能会返回 PostgreSQL 特定的数据类型,例如 sqlalchemy.dialects.postgresql.INTERVALsqlalchemy.dialects.postgresql.ENUM

反射有一个用例,即给定的 Table 将被传输到另一个供应商数据库。为了适应这种情况,有一种技术可以将这些供应商特定的数据类型动态转换为 SQLAlchemy 后端无关数据类型的实例,例如上面的示例类型,例如 IntegerIntervalEnum。这可以通过使用 DDLEvents.column_reflect() 事件与 TypeEngine.as_generic() 方法来拦截列反射来实现。

在 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 独有的整数类型 MEDIUMINTTINYINT,以及一个包含 MySQL 独有的 CHARACTER SET 选项的 VARCHAR。如果我们通常反射该表,它会生成一个 Table 对象,该对象将包含这些 MySQL 特定的数据类型和选项

>>> 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.MEDIUMINTsqlalchemy.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 自增数据类型。

New in version 1.4: 添加了 TypeEngine.as_generic() 方法,此外还改进了 DDLEvents.column_reflect() 事件的使用,以便它可以方便地应用于 MetaData 对象。

反射的局限性

需要注意的是,反射过程仅使用关系数据库中表示的信息来重新创建Table 元数据。根据定义,此过程无法恢复数据库中未实际存储的模式方面。反射无法获取的状态包括但不限于

  • 客户端默认值,无论是使用 default 关键字定义的 Python 函数还是 SQL 表达式 Column(注意,这与 server_default 不同,后者是通过反射可以获取的)。

  • 列信息,例如可能已放置在 Column.info 字典中的数据

  • .quote 设置的值 ColumnTable

  • 特定 Sequence 与给定 Column 的关联

在很多情况下,关系数据库以与 SQLAlchemy 中指定的格式不同的格式报告表元数据。从反射返回的 Table 对象不能始终依赖于产生与最初定义的 Python Table 对象相同的 DDL。发生这种情况的领域包括服务器默认值、与列关联的序列以及有关约束和数据类型的各种特殊情况。服务器端默认值可能会使用强制转换指令返回(通常 PostgreSQL 将包含 ::<type> 强制转换)或与最初指定的不同的引用模式。

另一类限制包括仅部分或尚未定义反射的模式结构。对反射的最新改进允许反射诸如视图、索引和外键选项之类的内容。截至撰写本文时,诸如 CHECK 约束、表注释和触发器之类的结构尚未反射。