反射数据库对象

一个 Table 对象可以被指示从数据库中已存在的相应数据库 schema 对象加载关于自身的信息。这个过程称为反射。在最简单的情况下,你只需要指定表名,一个 MetaData 对象,以及 autoload_with 参数

>>> messages = Table("messages", metadata_obj, autoload_with=engine)
>>> [c.name for c in messages.columns]
['message_id', 'message_name', 'date']

上述操作将使用给定的 engine 查询数据库,以获取关于 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 是一个 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())

从其他 Schema 反射表

指定 Schema 名称 部分介绍了表 schema 的概念,表 schema 是数据库中的命名空间,包含表和其他对象,并且可以显式指定。Table 对象以及视图、索引和序列等其他对象的 “schema” 可以使用 Table.schema 参数进行设置,也可以使用 MetaData.schema 参数将其设置为 MetaData 对象的默认 schema。

schema 参数的使用直接影响表反射功能在被要求反射对象时查找的位置。例如,给定一个通过 MetaData.schema 参数配置了默认 schema 名称 “project” 的 MetaData 对象。

>>> metadata_obj = MetaData(schema="project")

MetaData.reflect() 然后将使用配置的 .schema 进行反射。

>>> # uses `schema` configured in metadata_obj
>>> metadata_obj.reflect(someengine)

最终结果是,来自 “project” schema 的 Table 对象将被反射,并且它们将以 schema 限定的方式填充该名称。

>>> metadata_obj.tables["project.messages"]
Table('messages', MetaData(), Column('message_id', INTEGER(), table=<messages>), schema='project')

类似地,包含 Table.schema 参数的单个 Table 对象也将从该数据库 schema 反射,从而覆盖可能在所属 MetaData 集合上配置的任何默认 schema。

>>> 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” schema 加载表。

>>> 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)

Schema 限定反射与默认 Schema 的交互

最佳实践总结部分

在本节中,我们讨论 SQLAlchemy 关于数据库会话的 “默认 schema” 中可见的表的反射行为,以及这些行为如何与显式包含 schema 的 SQLAlchemy 指令交互。作为最佳实践,请确保数据库的 “默认” schema 只是一个名称,而不是名称列表;对于属于此 “默认” schema 并且可以在 DDL 和 SQL 中命名而无需 schema 限定的表,请将相应的 Table.schema 和类似的 schema 参数设置为默认值 None

使用 MetaData 指定默认 Schema 名称 中所述,具有 schema 概念的数据库通常也包含 “默认” schema 的概念。这样做的原因很自然,因为当人们在没有 schema 的情况下引用表对象(这是很常见的)时,支持 schema 的数据库仍然会认为该表位于某个 “schema” 中。某些数据库(如 PostgreSQL)将此概念进一步扩展到 schema 搜索路径 的概念,其中多个 schema 名称可以在特定的数据库会话中被认为是 “隐式的”;引用属于这些 schema 中任何一个的表名不需要 schema 名称出现(同时,如果 schema 名称出现,也完全可以)。

由于大多数关系数据库因此具有特定表对象的概念,该对象可以以 schema 限定的方式以及没有 schema 的 “隐式” 方式引用,这给 SQLAlchemy 的反射功能带来了一定的复杂性。以 schema 限定的方式反射表将始终填充其 Table.schema 属性,并额外影响此 Table 如何组织到 MetaData.tables 集合中,即以 schema 限定的方式。相反,以非 schema 限定的方式反射同一个表将将其组织到 进行 schema 限定的 MetaData.tables 集合中。最终结果是,在单个 MetaData 集合中将有两个单独的 Table 对象,它们代表实际数据库中的同一个表。

为了说明此问题的影响,请考虑前面示例中 “project” schema 中的表,并假设 “project” schema 也是我们数据库连接的默认 schema,或者如果使用 PostgreSQL 等数据库,则假设 “project” schema 在 PostgreSQL search_path 中设置。这将意味着数据库接受以下两个 SQL 语句是等效的。

-- schema qualified
SELECT message_id FROM project.messages

-- non-schema qualified
SELECT message_id FROM messages

这不是问题,因为可以通过两种方式找到该表。但是,在 SQLAlchemy 中,是 Table 对象的标识决定了其在 SQL 语句中的语义角色。根据 SQLAlchemy 中的当前决策,这意味着如果我们以 schema 限定和非 schema 限定两种方式反射同一个 “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” 列,该列引用另一个 schema 本地表 “projects” 中的行,这意味着有一个 ForeignKeyConstraint 对象是 “messages” 表定义的一部分。

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

常见的情况是以 schema 限定的方式反射表,然后加载相关的表,这也将以 schema 限定的方式执行。

>>> # reflect "messages" in a schema qualified fashion
>>> messages_table_1 = Table(
...     "messages", metadata_obj, schema="project", autoload_with=someengine
... )

上面的 messages_table_1 将以 schema 限定的方式引用 projects。这个 “projects” 表将因 “messages” 引用它而被自动反射。

>>> messages_table_1.c.project_id
Column('project_id', INTEGER(), ForeignKey('project.projects.project_id'), table=<messages>)

如果代码的某些其他部分以非 schema 限定的方式反射 “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 检测新表和外键约束时。

通过坚持一个简单的实践可以补救上述行为。

  • 对于任何希望位于数据库默认 schema 中的 Table,请不要包含 Table.schema 参数。

对于 PostgreSQL 和其他支持 schema “搜索” 路径的数据库,添加以下额外的实践。

  • 将 “搜索路径” 缩小到仅一个 schema,即默认 schema

另请参阅

远程 Schema 表内省和 PostgreSQL search_path - 关于 PostgreSQL 数据库的这种行为的更多详细信息。

使用 Inspector 进行细粒度反射

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

from sqlalchemy import create_engine
from sqlalchemy import inspect

engine = create_engine("...")
insp = inspect(engine)
print(insp.get_table_names())
对象名称 描述

Inspector

执行数据库 schema 检查。

ReflectedCheckConstraint

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

ReflectedColumn

字典,表示与 Column 对象对应的反射元素。

ReflectedComputed

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

ReflectedForeignKeyConstraint

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

ReflectedIdentity

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

ReflectedIndex

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

ReflectedPrimaryKeyConstraint

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

ReflectedTableComment

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

ReflectedUniqueConstraint

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

sqlalchemy.engine.reflection.Inspector

执行数据库 schema 检查。

Inspector 充当 Dialect 反射方法的代理,提供一致的接口以及对先前获取的元数据的缓存支持。

一个 Inspector 对象通常通过 inspect() 函数创建,该函数可以传递一个 Engine 或一个 Connection

from sqlalchemy import inspect, create_engine

engine = create_engine("...")
insp = inspect(engine)

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

类签名

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

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

初始化一个新的 Inspector

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

参数:

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

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

属性 sqlalchemy.engine.reflection.Inspector.bind: Engine | Connection
方法 sqlalchemy.engine.reflection.Inspector.clear_cache() None

重置此 Inspector 的缓存。

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

2.0 版本新增。

属性 sqlalchemy.engine.reflection.Inspector.default_schema_name

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

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

属性 sqlalchemy.engine.reflection.Inspector.dialect: Dialect
属性 sqlalchemy.engine.reflection.Inspector.engine: Engine
类方法 sqlalchemy.engine.reflection.Inspector.from_engine(bind: Engine) Inspector

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

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

参数:

bind – 一个 ConnectionEngine

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

请参阅 Inspector 中的示例。

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

返回:

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

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

返回:

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

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

返回:

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

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

返回:

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

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

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

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

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

2.0 版本新增。

方法 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 版本新增。

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

返回:

一个字典,其中键是二元组 (schema, table-name),值是字典列表,每个字典代表一个数据库列的定义。如果未提供模式,则 schema 为 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 – 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅所用方言的文档。

返回:

一个字典,其中键是二元组 (schema, table-name),值是字典列表,每个字典代表一个外键定义。如果未提供模式,则 schema 为 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 – 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅所用方言的文档。

返回:

一个字典,其中键是二元组 (schema, table-name),值是字典列表,每个字典代表一个索引的定义。如果未提供模式,则 schema 为 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 – 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅所用方言的文档。

返回:

一个字典,其中键是二元组 (schema, table-name),值是字典,每个字典代表一个主键约束的定义。如果未提供模式,则 schema 为 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 – 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅所用方言的文档。

返回:

一个字典,其中键是二元组 (schema, table-name),值是字典,表示表注释。如果未提供模式,则 schema 为 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 – 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅所用方言的文档。

返回:

一个字典,其中键是二元组 (schema, table-name),值是包含表选项的字典。每个字典中返回的键取决于所使用的方言。每个键都以方言名称为前缀。如果未提供模式,则 schema 为 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 – 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅所用方言的文档。

返回:

一个字典,其中键是二元组 (schema, table-name),值是字典列表,每个字典代表一个唯一约束的定义。如果未提供模式,则 schema 为 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 – 传递给特定方言实现的附加关键字参数。有关更多信息,请参阅所用方言的文档。

返回:

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

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

返回所有模式名称。

参数:

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

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

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

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

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

方法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), ..]),它将包含其余的外键约束名称,这些名称将需要根据表之间的依赖关系在事后执行单独的 CREATE 步骤。

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

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

另请参阅

Inspector.get_table_names()

sort_tables_and_constraints() - 类似的方法,适用于已给定的 MetaData

方法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 版本中的新功能。

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

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

返回:

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

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

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

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

参数:

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

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

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

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

参数:

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

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

返回:

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

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

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

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

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

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

在 2.0 版本中变更: 对于先前在此列表中包含物化视图名称的方言(目前为 PostgreSQL),此方法不再返回物化视图的名称。 应该改用 Inspector.get_materialized_view_names() 方法。

方法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 版本新增。

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

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

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

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

2.0 版本新增。

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

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

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

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

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

1.4 版本中的新功能。

方法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 自带方言的支持。 但是,第三方方言的支持可能会滞后。

属性 sqlalchemy.engine.reflection.Inspector.info_cache: Dict[Any, Any]
方法 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,则反射所有列。

方法 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 版本新增。

sqlalchemy.engine.interfaces.ReflectedColumn

字典,表示与 Column 对象对应的反射元素。

ReflectedColumn 结构由 get_columns 方法返回。

类签名

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

属性 sqlalchemy.engine.interfaces.ReflectedColumn.autoincrement: NotRequired[bool]

数据库相关的自增标志。

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

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

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

列的注释(如果存在)。 只有一些方言返回此键

属性 sqlalchemy.engine.interfaces.ReflectedColumn.computed: NotRequired[ReflectedComputed]

指示此列由数据库计算。 只有一些方言返回此键。

1.3.16 版本新增: - 添加了对计算列反射的支持。

属性 sqlalchemy.engine.interfaces.ReflectedColumn.default: str | None

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

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

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

属性 sqlalchemy.engine.interfaces.ReflectedColumn.identity: NotRequired[ReflectedIdentity]

指示此列是 IDENTITY 列。 只有一些方言返回此键。

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

属性 sqlalchemy.engine.interfaces.ReflectedColumn.name: str

列名

属性 sqlalchemy.engine.interfaces.ReflectedColumn.nullable: bool

布尔标志,指示列是否为 NULL 或 NOT NULL

属性 sqlalchemy.engine.interfaces.ReflectedColumn.type: TypeEngine[Any]

列类型,表示为 TypeEngine 实例。

sqlalchemy.engine.interfaces.ReflectedComputed

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

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

成员

persisted, sqltext

类签名

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

属性 sqlalchemy.engine.interfaces.ReflectedComputed.persisted: NotRequired[bool]

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

属性 sqlalchemy.engine.interfaces.ReflectedComputed.sqltext: str

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

sqlalchemy.engine.interfaces.ReflectedCheckConstraint

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

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

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

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

1.3.8 版本新增。

属性 sqlalchemy.engine.interfaces.ReflectedCheckConstraint.sqltext: str

检查约束的 SQL 表达式

sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint

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

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

属性 sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint.constrained_columns: List[str]

构成外键的本地列名

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

为此外键约束检测到的其他选项

属性 sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint.referred_columns: List[str]

constrained_columns 对应的被引用列名

属性 sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint.referred_schema: str | None

被引用表的模式名

属性 sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint.referred_table: str

被引用表的名称

sqlalchemy.engine.interfaces.ReflectedIdentity

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

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

类签名

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

属性 sqlalchemy.engine.interfaces.ReflectedIdentity.always: bool

identity 列的类型

属性 sqlalchemy.engine.interfaces.ReflectedIdentity.cache: int | None

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

属性 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 对应的反射元素。

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

类签名

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 子句中的列。

Deprecated since version 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 对应的反射元素。

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

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() 方法返回。

成员

文本

类签名

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 是因为 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,以及一个 VARCHAR,其中包括仅 MySQL 的 CHARACTER SET 选项。 如果我们正常反射此表,它会生成一个 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,我们可以将其干净地转移到另一个数据库供应商,将特殊数据类型 sqlalchemy.dialects.mysql.MEDIUMINTsqlalchemy.dialects.mysql.TINYINT 替换为 Integer,我们可以选择 “通用化” 此表上的数据类型,或者通过使用 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: 在 1.4 版本中新增:添加了 TypeEngine.as_generic() 方法,并改进了 DDLEvents.column_reflect() 事件的使用,使其可以方便地应用于 MetaData 对象。

反射的局限性

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

  • 客户端默认值,无论是 Python 函数还是使用 Columndefault 关键字定义的 SQL 表达式(请注意,这与 server_default 是分开的,后者专门是通过反射可用的内容)。

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

  • ColumnTable.quote 设置的值

  • 特定的 Sequence 与给定的 Column 的关联

在许多情况下,关系数据库还以与 SQLAlchemy 中指定的格式不同的格式报告表元数据。 从反射返回的 Table 对象不能总是可靠地生成与原始 Python 定义的 Table 对象相同的 DDL。 发生这种情况的区域包括服务器默认值、与列关联的序列以及关于约束和数据类型的各种特性。 服务器端默认值可能会与强制转换指令一起返回(通常 PostgreSQL 会包含 ::<type> 强制转换)或与原始指定的引用模式不同的引用模式。

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