Reflecting Database Objects

Table オブジェクトは、データベース内に既に存在する対応するデータベーススキーマオブジェクトから、自身に関する情報を読み込むように指示することができます。このプロセスは*reflection*と呼ばれます。最も単純なケースでは、テーブル名、 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で手作業で作成されたかのように生成します。

テーブルが反映されるとき、もし与えられたテーブルが他のテーブルを外部キー経由で参照している場合、2番目の Table オブジェクトが MetaData オブジェクト内に作成され、接続を表します。以下では、テーブル shopping_cart_itemsshopping_carts という名前のテーブルを参照していると仮定します。

>>> shopping_cart_items = Table("shopping_cart_items", metadata_obj, autoload_with=engine)
>>> "shopping_carts" in metadata_obj.tables
True

MetaData は興味深い”シングルトンのような”振る舞いをします。例えば、両方のテーブルを個別に要求した場合、 MetaData は、それぞれのテーブル名に対して1つの Table オブジェクトが作成されることを保証します。 Table コンストラクタは、指定された名前で既に存在する場合、実際には既に存在する Table オブジェクトを返します。以下のように、すでに生成された shopping_carts テーブルに名前を付けるだけでアクセスできます:

shopping_carts = Table("shopping_carts", metadata_obj)

もちろん、上記のテーブルで autoload_with=engine を使用するのは良い考えです。これは、テーブルの属性がまだロードされていない場合にロードされるようにするためです。自動ロード操作は、まだロードされていないテーブルに対してのみ行われます。一度ロードされると、同じ名前で Table を新たに呼び出しても、リフレクションクエリは再発行されません。

Overriding Reflected Columns

リフレクトされたテーブルでは、個々の列を明示的な値で上書きすることができます。これは、カスタムデータ型や、データベース内で設定されていない主キーなどの制約を指定する場合に便利です。:

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

See also

Working with Custom Types and Reflection - 上記の列オーバーライドのテクニックが、テーブルリフレクションを持つカスタムデータ型の使用にどのように適用されるかを示します。

Reflecting Views

対称システムはビューも対称にできます。基本的な使い方はテーブルの使い方と同じです:

my_view = Table("some_view", metadata, autoload_with=engine)

上の例では、 my_viewTable オブジェクトで、 Column オブジェクトはビュー”some_view”内の各列の名前と型を表しています。

通常、ビューを反映する際には、外部キーではないにしても、少なくとも主キー制約を持つことが望まれます。ビューの反映は、これらの制約を推定しません。

これには”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,
)

Reflecting All Tables at Once

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

Reflecting Tables from Other Schemas

セクション Specifying the Schema Name では、テーブルスキーマの概念を紹介しています。テーブルスキーマは、テーブルやその他のオブジェクトを含むデータベース内の名前空間であり、明示的に指定することができます。 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.reflect() を異なる MetaData.schema 引数で何回でも(あるいは何も指定せずに)呼び出すことで、 MetaData オブジェクトにさらにオブジェクトを追加することができます:

>>> # add tables from the "customer" schema
>>> metadata_obj.reflect(someengine, schema="customer")
>>> # add tables from the default schema
>>> metadata_obj.reflect(someengine)

Interaction of Schema-qualified Reflection with the Default Schema

セクションのベストプラクティスのまとめ

このセクションでは、データベースセッションの”デフォルトスキーマ”に表示されるテーブルに関するSQLAlchemyのリフレクションの動作と、これらがスキーマを明示的に含むSQLAlchemyディレクティブとどのように相互作用するかについて説明します。ベストプラクティスとして、データベースの”デフォルト”スキーマが、名前のリストではなく、単一の名前であることを確認してください。この”デフォルト”スキーマの一部であり、DDLおよびSQLでスキーマ修飾なしで名前を付けることができるテーブルについては、対応する Table.schema および同様のスキーマパラメータをデフォルトの None に設定したままにしてください。

Specifying a Default Schema Name with MetaData で説明されているように、スキーマの概念を持つデータベースには通常、”デフォルト”スキーマの概念も含まれています。その理由は、一般的にスキーマなしでテーブルオブジェクトを参照する場合、スキーマ対応のデータベースはそのテーブルがどこかの”スキーマ”にあると考えるからです。PostgreSQLのようないくつかのデータベースでは、この概念をさらに schema search path の概念に取り入れています。ここで、特定のデータベースセッションでは*複数の*スキーマ名を”暗黙的”と見なすことができます。これらのスキーマのいずれかであるテーブル名を参照する場合、スキーマ名が存在する必要はありません(同時に、スキーマ名が*存在する*場合も完全に問題ありません)。

したがって、ほとんどのリレーショナルデータベースは、スキーマ修飾された方法と、スキーマが存在しない「暗黙的な」方法の両方で参照できる特定のテーブルオブジェクトの概念を持っているので、これはSQLAlchemyのリフレクション機能を複雑にします。スキーマ修飾された方法でテーブルを反映すると、常にその Table.schema 属性が設定され、さらにこの TableMetaData.tables コレクションにどのように編成されるかにも影響します。つまり、スキーマ修飾された方法です。逆に、スキーマ修飾されていない方法で**同じ**テーブルを反映すると、 スキーマ修飾されずに MetaData.tables コレクションに編成されます。最終的には、実際のデータベース内の同じテーブルを表す単一の MetaData コレクション内に、2つの別々の Table オブジェクトが存在することになります。

この問題の影響を説明するために、前の例の”project”スキーマのテーブルを考え、”project”スキーマがデータベース接続のデフォルトスキーマであると仮定します。あるいは、PostgreSQLのようなデータベースを使用している場合、”project”スキーマがPostgreSQLの search_path に設定されていると仮定します。これは、データベースが次の2つのSQL文を等価として受け入れることを意味します。

-- schema qualified
SELECT message_id FROM project.messages

-- non-schema qualified
SELECT message_id FROM messages

テーブルは両方の方法で見つけることができるので、これは問題ではありません。しかし、SQLAlchemyでは、SQL文内での意味的な役割を決定するのは、 Table オブジェクトの**identity**です。SQLAlchemy内での現在の決定に基づいて、同じ”メッセージ”テーブルをスキーマ修飾と非スキーマ修飾の両方の方法で反映すると、意味的に等価として 扱われない 2つの 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”が別のスキーマローカルテーブル”projects”の行を参照する”project_id”列を持っているとします。つまり、”messages”テーブルの定義の一部である ForeignKeyConstraint オブジェクトがあるということです。

1つの MetaData コレクションに、これら2つのデータベーステーブルを表す Table オブジェクトが4つまで含まれる場合があります。この場合、追加テーブルの1つまたは2つがリフレクションプロセスによって生成されています。これは、リフレクションプロセスがリフレクションされているテーブルで外部キー制約を検出すると、その参照先テーブルも反映するように分岐するためです。この参照先テーブルにスキーマを割り当てるために使用される決定は、所有する Table もスキーマ名を省略している場合、SQLAlchemyは反映された ForeignKeyConstraint オブジェクトからデフォルトスキーマを**省略**します。また、これら2つのオブジェクトは同じスキーマ内にありますが、省略されていない場合は 包含 します。

一般的なシナリオは、スキーマ修飾された方法でテーブルを反映した後、関連するテーブルをロードし、そのテーブルもスキーマ修飾された方法で実行される場合です。:

>>> # 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”を反映している場合、同じではない2つのプロジェクトテーブルが存在します:

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

上記の混乱は、tablereflectionを使用してアプリケーションレベルの Table オブジェクトをロードするアプリケーション内や、特にAlembicMigrationsを使用して新しいテーブルや外部キー制約を検出する場合などの移行シナリオ内で問題を引き起こす可能性があります。

上記の動作は、1つの簡単なプラクティスに固執することで改善できます。:

  • データベースの デフォルト スキーマにあると想定される Table には Table.schema パラメータを含めないでください。

スキーマの”検索”パスをサポートするPostgreSQLおよびその他のデータベースでは、以下の追加のプラクティスを追加します。

  • “検索パス”を デフォルトのスキーマである1つのスキーマのみ に絞り込みます。

See also

Remote-Schema Table Introspection and PostgreSQL search_path-PostgreSQLデータベースに関するこの動作の詳細です。

Fine Grained Reflection with Inspector

与えられたデータベースからスキーマ、テーブル、列、制約記述のリストをロードする、バックエンドに依存しないシステムを提供する低レベルのインターフェースも利用できます。これは”Inspector”として知られています:

from sqlalchemy import create_engine
from sqlalchemy import inspect

engine = create_engine("...")
insp = inspect(engine)
print(insp.get_table_names())
Object Name Description

Inspector

Performs database schema inspection.

ReflectedCheckConstraint

Dictionary representing the reflected elements corresponding to CheckConstraint.

ReflectedColumn

Dictionary representing the reflected elements corresponding to a Column object.

ReflectedComputed

Represent the reflected elements of a computed column, corresponding to the Computed construct.

ReflectedForeignKeyConstraint

Dictionary representing the reflected elements corresponding to ForeignKeyConstraint.

ReflectedIdentity

represent the reflected IDENTITY structure of a column, corresponding to the Identity construct.

ReflectedIndex

Dictionary representing the reflected elements corresponding to Index.

ReflectedPrimaryKeyConstraint

Dictionary representing the reflected elements corresponding to PrimaryKeyConstraint.

ReflectedTableComment

Dictionary representing the reflected comment corresponding to the Table.comment attribute.

ReflectedUniqueConstraint

Dictionary representing the reflected elements corresponding to UniqueConstraint.

class sqlalchemy.engine.reflection.Inspector

Performs database schema inspection.

The Inspector acts as a proxy to the reflection methods of the Dialect, providing a consistent interface as well as caching support for previously fetched metadata.

A Inspector object is usually created via the inspect() function, which may be passed an Engine or a Connection:

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

Where above, the Dialect associated with the engine may opt to return an Inspector subclass that provides additional methods specific to the dialect’s target database.

Class signature

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

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

Initialize a new Inspector.

Deprecated since version 1.4: The __init__() method on Inspector is deprecated and will be removed in a future release. Please use the inspect() function on an Engine or Connection in order to acquire an Inspector.

Parameters:

bind – a Connection, which is typically an instance of Engine or Connection.

For a dialect-specific instance of Inspector, see Inspector.from_engine()

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

reset the cache for this Inspector.

Inspection methods that have data cached will emit SQL queries when next called to get new data.

New in version 2.0.

attribute sqlalchemy.engine.reflection.Inspector.default_schema_name

Return the default schema name presented by the dialect for the current engine’s database user.

E.g. this is typically public for PostgreSQL and dbo for SQL Server.

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

Construct a new dialect-specific Inspector object from the given engine or connection.

Deprecated since version 1.4: The from_engine() method on Inspector is deprecated and will be removed in a future release. Please use the inspect() function on an Engine or Connection in order to acquire an Inspector.

Parameters:

bind – a Connection or Engine.

This method differs from direct a direct constructor call of Inspector in that the Dialect is given a chance to provide a dialect-specific Inspector instance, which may provide additional methods.

See the example at Inspector.

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

Return information about check constraints in table_name.

Given a string table_name and an optional string schema, return check constraint information as a list of ReflectedCheckConstraint.

Parameters:
  • table_name – string name of the table. For special quoting, use quoted_name.

  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a list of dictionaries, each representing the definition of a check constraints.

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

Return information about columns in table_name.

Given a string table_name and an optional string schema, return column information as a list of ReflectedColumn.

Parameters:
  • table_name – string name of the table. For special quoting, use quoted_name.

  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

list of dictionaries, each representing the definition of a database column.

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

Return information about foreign_keys in table_name.

Given a string table_name, and an optional string schema, return foreign key information as a list of ReflectedForeignKeyConstraint.

Parameters:
  • table_name – string name of the table. For special quoting, use quoted_name.

  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a list of dictionaries, each representing the a foreign key definition.

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

Return information about indexes in table_name.

Given a string table_name and an optional string schema, return index information as a list of ReflectedIndex.

Parameters:
  • table_name – string name of the table. For special quoting, use quoted_name.

  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a list of dictionaries, each representing the definition of an index.

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

Return all materialized view names in schema.

Parameters:
  • schema – Optional, retrieve names from a non-default schema. For special quoting, use quoted_name.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

New in version 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]]

Return information about check constraints in all tables in the given schema.

The tables can be filtered by passing the names to use to filter_names.

For each table the value is a list of ReflectedCheckConstraint.

Parameters:
  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • filter_names – optionally return information only for the objects listed here.

  • kind – a ObjectKind that specifies the type of objects to reflect. Defaults to ObjectKind.TABLE.

  • scope – a ObjectScope that specifies if constraints of default, temporary or any tables should be reflected. Defaults to ObjectScope.DEFAULT.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a dictionary where the keys are two-tuple schema,table-name and the values are list of dictionaries, each representing the definition of a check constraints. The schema is None if no schema is provided.

New in version 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]]

Return information about columns in all objects in the given schema.

The objects can be filtered by passing the names to use to filter_names.

For each table the value is a list of ReflectedColumn.

Parameters:
  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • filter_names – optionally return information only for the objects listed here.

  • kind – a ObjectKind that specifies the type of objects to reflect. Defaults to ObjectKind.TABLE.

  • scope – a ObjectScope that specifies if columns of default, temporary or any tables should be reflected. Defaults to ObjectScope.DEFAULT.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a dictionary where the keys are two-tuple schema,table-name and the values are list of dictionaries, each representing the definition of a database column. The schema is None if no schema is provided.

New in version 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]]

Return information about foreign_keys in all tables in the given schema.

The tables can be filtered by passing the names to use to filter_names.

For each table the value is a list of ReflectedForeignKeyConstraint.

Parameters:
  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • filter_names – optionally return information only for the objects listed here.

  • kind – a ObjectKind that specifies the type of objects to reflect. Defaults to ObjectKind.TABLE.

  • scope – a ObjectScope that specifies if foreign keys of default, temporary or any tables should be reflected. Defaults to ObjectScope.DEFAULT.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a dictionary where the keys are two-tuple schema,table-name and the values are list of dictionaries, each representing a foreign key definition. The schema is None if no schema is provided.

New in version 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]]

Return information about indexes in in all objects in the given schema.

The objects can be filtered by passing the names to use to filter_names.

For each table the value is a list of ReflectedIndex.

Parameters:
  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • filter_names – optionally return information only for the objects listed here.

  • kind – a ObjectKind that specifies the type of objects to reflect. Defaults to ObjectKind.TABLE.

  • scope – a ObjectScope that specifies if indexes of default, temporary or any tables should be reflected. Defaults to ObjectScope.DEFAULT.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a dictionary where the keys are two-tuple schema,table-name and the values are list of dictionaries, each representing the definition of an index. The schema is None if no schema is provided.

New in version 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]

Return information about primary key constraints in all tables in the given schema.

The tables can be filtered by passing the names to use to filter_names.

For each table the value is a ReflectedPrimaryKeyConstraint.

Parameters:
  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • filter_names – optionally return information only for the objects listed here.

  • kind – a ObjectKind that specifies the type of objects to reflect. Defaults to ObjectKind.TABLE.

  • scope – a ObjectScope that specifies if primary keys of default, temporary or any tables should be reflected. Defaults to ObjectScope.DEFAULT.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a dictionary where the keys are two-tuple schema,table-name and the values are dictionaries, each representing the definition of a primary key constraint. The schema is None if no schema is provided.

New in version 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]

Return information about the table comment in all objects in the given schema.

The objects can be filtered by passing the names to use to filter_names.

For each table the value is a ReflectedTableComment.

Raises NotImplementedError for a dialect that does not support comments.

Parameters:
  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • filter_names – optionally return information only for the objects listed here.

  • kind – a ObjectKind that specifies the type of objects to reflect. Defaults to ObjectKind.TABLE.

  • scope – a ObjectScope that specifies if comments of default, temporary or any tables should be reflected. Defaults to ObjectScope.DEFAULT.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a dictionary where the keys are two-tuple schema,table-name and the values are dictionaries, representing the table comments. The schema is None if no schema is provided.

New in version 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]]

Return a dictionary of options specified when the tables in the given schema were created.

The tables can be filtered by passing the names to use to filter_names.

This currently includes some options that apply to MySQL and Oracle tables.

Parameters:
  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • filter_names – optionally return information only for the objects listed here.

  • kind – a ObjectKind that specifies the type of objects to reflect. Defaults to ObjectKind.TABLE.

  • scope – a ObjectScope that specifies if options of default, temporary or any tables should be reflected. Defaults to ObjectScope.DEFAULT.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a dictionary where the keys are two-tuple schema,table-name and the values are dictionaries with the table options. The returned keys in each dict depend on the dialect in use. Each one is prefixed with the dialect name. The schema is None if no schema is provided.

New in version 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]]

Return information about unique constraints in all tables in the given schema.

The tables can be filtered by passing the names to use to filter_names.

For each table the value is a list of ReflectedUniqueConstraint.

Parameters:
  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • filter_names – optionally return information only for the objects listed here.

  • kind – a ObjectKind that specifies the type of objects to reflect. Defaults to ObjectKind.TABLE.

  • scope – a ObjectScope that specifies if constraints of default, temporary or any tables should be reflected. Defaults to ObjectScope.DEFAULT.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a dictionary where the keys are two-tuple schema,table-name and the values are list of dictionaries, each representing the definition of an unique constraint. The schema is None if no schema is provided.

New in version 2.0.

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

Return information about primary key constraint in table_name.

Given a string table_name, and an optional string schema, return primary key information as a ReflectedPrimaryKeyConstraint.

Parameters:
  • table_name – string name of the table. For special quoting, use quoted_name.

  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a dictionary representing the definition of a primary key constraint.

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

Return all schema names.

Parameters:

**kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

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

Return all sequence names in schema.

Parameters:
  • schema – Optional, retrieve names from a non-default schema. For special quoting, use quoted_name.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

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

Return dependency-sorted table and foreign key constraint names in referred to within a particular schema.

This will yield 2-tuples of (tablename, [(tname, fkname), (tname, fkname), ...]) consisting of table names in CREATE order grouped with the foreign key constraint names that are not detected as belonging to a cycle. The final element will be (None, [(tname, fkname), (tname, fkname), ..]) which will consist of remaining foreign key constraint names that would require a separate CREATE step after-the-fact, based on dependencies between tables.

Parameters:
  • schema – schema name to query, if not the default schema.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

See also

Inspector.get_table_names()

sort_tables_and_constraints() - similar method which works with an already-given MetaData.

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

Return information about the table comment for table_name.

Given a string table_name and an optional string schema, return table comment information as a ReflectedTableComment.

Raises NotImplementedError for a dialect that does not support comments.

Parameters:
  • table_name – string name of the table. For special quoting, use quoted_name.

  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a dictionary, with the table comment.

New in version 1.2.

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

Return all table names within a particular schema.

The names are expected to be real tables only, not views. Views are instead returned using the Inspector.get_view_names() and/or Inspector.get_materialized_view_names() methods.

Parameters:
  • schema – Schema name. If schema is left at None, the database’s default schema is used, else the named schema is searched. If the database does not support named schemas, behavior is undefined if schema is not passed as None. For special quoting, use quoted_name.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

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

Return a dictionary of options specified when the table of the given name was created.

This currently includes some options that apply to MySQL and Oracle tables.

Parameters:
  • table_name – string name of the table. For special quoting, use quoted_name.

  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a dict with the table options. The returned keys depend on the dialect in use. Each one is prefixed with the dialect name.

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

Return a list of temporary table names for the current bind.

This method is unsupported by most dialects; currently only Oracle, PostgreSQL and SQLite implements it.

Parameters:

**kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

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

Return a list of temporary view names for the current bind.

This method is unsupported by most dialects; currently only PostgreSQL and SQLite implements it.

Parameters:

**kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

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

Return information about unique constraints in table_name.

Given a string table_name and an optional string schema, return unique constraint information as a list of ReflectedUniqueConstraint.

Parameters:
  • table_name – string name of the table. For special quoting, use quoted_name.

  • schema – string schema name; if omitted, uses the default schema of the database connection. For special quoting, use quoted_name.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Returns:

a list of dictionaries, each representing the definition of an unique constraint.

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

Return definition for the plain or materialized view called view_name.

Parameters:
  • view_name – Name of the view.

  • schema – Optional, retrieve names from a non-default schema. For special quoting, use quoted_name.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

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

Return all non-materialized view names in schema.

Parameters:
  • schema – Optional, retrieve names from a non-default schema. For special quoting, use quoted_name.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

Changed in version 2.0: For those dialects that previously included the names of materialized views in this list (currently PostgreSQL), this method no longer returns the names of materialized views. the Inspector.get_materialized_view_names() method should be used instead.

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

Check the existence of a particular index name in the database.

Parameters:
  • table_name – the name of the table the index belongs to

  • index_name – the name of the index to check

  • schema – schema name to query, if not the default schema.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

New in version 2.0.

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

Return True if the backend has a schema with the given name.

Parameters:
  • schema_name – name of the schema to check

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

New in version 2.0.

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

Return True if the backend has a sequence with the given name.

Parameters:
  • sequence_name – name of the sequence to check

  • schema – schema name to query, if not the default schema.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

New in version 1.4.

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

Return True if the backend has a table, view, or temporary table of the given name.

Parameters:
  • table_name – name of the table to check

  • schema – schema name to query, if not the default schema.

  • **kw – Additional keyword argument to pass to the dialect specific implementation. See the documentation of the dialect in use for more information.

New in version 1.4: - the Inspector.has_table() method replaces the Engine.has_table() method.

Changed in version 2.0::: Inspector.has_table() now formally supports checking for additional table-like objects:

  • any type of views (plain or materialized)

  • temporary tables of any kind

Previously, these two checks were not formally specified and different dialects would vary in their behavior. The dialect testing suite now includes tests for all of these object types and should be supported by all SQLAlchemy-included dialects. Support among third party dialects may be lagging, however.

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

Given a Table object, load its internal constructs based on introspection.

This is the underlying method used by most dialects to produce table reflection. Direct usage is like:

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)

Changed in version 1.4: Renamed from reflecttable to reflect_table

Parameters:
  • table – a Table instance.

  • include_columns – a list of string column names to include in the reflection process. If None, all columns are reflected.

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

Return dependency-sorted table and foreign key constraint names referred to within multiple schemas.

This method may be compared to Inspector.get_sorted_table_and_fkc_names(), which works on one schema at a time; here, the method is a generalization that will consider multiple schemas at once including that it will resolve for cross-schema foreign keys.

New in version 2.0.

class sqlalchemy.engine.interfaces.ReflectedColumn

Dictionary representing the reflected elements corresponding to a Column object.

The ReflectedColumn structure is returned by the get_columns method.

Class signature

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

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

database-dependent autoincrement flag.

This flag indicates if the column has a database-side “autoincrement” flag of some kind. Within SQLAlchemy, other kinds of columns may also act as an “autoincrement” column without necessarily having such a flag on them.

See Column.autoincrement for more background on “autoincrement”.

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

comment for the column, if present. Only some dialects return this key

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

indicates that this column is computed by the database. Only some dialects return this key.

New in version 1.3.16: - added support for computed reflection.

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

column default expression as a SQL string

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

Additional dialect-specific options detected for this reflected object

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

indicates this column is an IDENTITY column. Only some dialects return this key.

New in version 1.4: - added support for identity column reflection.

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

column name

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

boolean flag if the column is NULL or NOT NULL

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

column type represented as a TypeEngine instance.

class sqlalchemy.engine.interfaces.ReflectedComputed

Represent the reflected elements of a computed column, corresponding to the Computed construct.

The ReflectedComputed structure is part of the ReflectedColumn structure, which is returned by the Inspector.get_columns() method.

Members

persisted, sqltext

Class signature

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

attribute sqlalchemy.engine.interfaces.ReflectedComputed.persisted: bool

indicates if the value is stored in the table or computed on demand

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

the expression used to generate this column returned as a string SQL expression

class sqlalchemy.engine.interfaces.ReflectedCheckConstraint

Dictionary representing the reflected elements corresponding to CheckConstraint.

The ReflectedCheckConstraint structure is returned by the Inspector.get_check_constraints() method.

Class signature

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

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

Additional dialect-specific options detected for this check constraint

New in version 1.3.8.

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

the check constraint’s SQL expression

class sqlalchemy.engine.interfaces.ReflectedForeignKeyConstraint

Dictionary representing the reflected elements corresponding to ForeignKeyConstraint.

The ReflectedForeignKeyConstraint structure is returned by the Inspector.get_foreign_keys() method.

Class signature

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

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

local column names which comprise the foreign key

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

Additional options detected for this foreign key constraint

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

referred column names that correspond to constrained_columns

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

schema name of the table being referred

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

name of the table being referred

class sqlalchemy.engine.interfaces.ReflectedIdentity

represent the reflected IDENTITY structure of a column, corresponding to the Identity construct.

The ReflectedIdentity structure is part of the ReflectedColumn structure, which is returned by the Inspector.get_columns() method.

Class signature

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

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

type of identity column

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

number of future values in the sequence which are calculated in advance.

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

allows the sequence to wrap around when the maxvalue or minvalue has been reached.

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

increment value of the sequence

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

the maximum value of the sequence.

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

the minimum value of the sequence.

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

no maximum value of the sequence.

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

no minimum value of the sequence.

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

indicates ON NULL

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

if true, renders the ORDER keyword.

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

starting index of the sequence

class sqlalchemy.engine.interfaces.ReflectedIndex

Dictionary representing the reflected elements corresponding to Index.

The ReflectedIndex structure is returned by the Inspector.get_indexes() method.

Class signature

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

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

column names which the index references. An element of this list is None if it’s an expression and is returned in the expressions list.

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

optional dict mapping column names or expressions to tuple of sort keywords, which may include asc, desc, nulls_first, nulls_last.

New in version 1.3.5.

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

Additional dialect-specific options detected for this index

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

Indicates if this index mirrors a constraint with this name

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

Expressions that compose the index. This list, when present, contains both plain column names (that are also in column_names) and expressions (that are None in column_names).

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

columns to include in the INCLUDE clause for supporting databases.

Deprecated since version 2.0: Legacy value, will be replaced with index_dict["dialect_options"]["<dialect name>_include"]

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

index name

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

whether or not the index has a unique flag

class sqlalchemy.engine.interfaces.ReflectedPrimaryKeyConstraint

Dictionary representing the reflected elements corresponding to PrimaryKeyConstraint.

The ReflectedPrimaryKeyConstraint structure is returned by the Inspector.get_pk_constraint() method.

Class signature

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

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

column names which comprise the primary key

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

Additional dialect-specific options detected for this primary key

class sqlalchemy.engine.interfaces.ReflectedUniqueConstraint

Dictionary representing the reflected elements corresponding to UniqueConstraint.

The ReflectedUniqueConstraint structure is returned by the Inspector.get_unique_constraints() method.

Class signature

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

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

column names which comprise the unique constraint

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

Additional dialect-specific options detected for this unique constraint

attribute sqlalchemy.engine.interfaces.ReflectedUniqueConstraint.duplicates_index: str | None

Indicates if this unique constraint duplicates an index with this name

class sqlalchemy.engine.interfaces.ReflectedTableComment

Dictionary representing the reflected comment corresponding to the Table.comment attribute.

The ReflectedTableComment structure is returned by the Inspector.get_table_comment() method.

Members

text

Class signature

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

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

text of the comment

Reflecting with Database-Agnostic Types

TableTable.autoload_with パラメータ、または InspectorInspector.get_columns() メソッドのいずれかを使用してテーブルの列をリフレクトする場合、データ型は可能な限りターゲットデータベースに固有のものになります。つまり、MySQLデータベースから”integer”データ型がリフレクトされる場合、その型は”display_width”などのMySQL固有の属性を含む sqlalchemy.dialects.MySQL.INTEGER クラスで表されます。PostgreSQLでは、 sqlalchemy.dialects.PostgreSQL.INTERVALsqlalchemy.dialects.PostgreSQL.ENUM などのPostgreSQL固有のデータ型が返されることがあります。

リフレクションのユースケースとして、指定された Table が別のベンダのデータベースに転送される場合があります。このユースケースに対応するために、これらのベンダ固有のデータ型を、バックエンドに依存しないSQLAlchemyデータ型のインスタンスにその場で変換するテクニックがあります。上の例では、 Integer,:class:_types.Interval,:class:_types.Enum などがあります。これは、 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専用の CHARACTERSET オプションを含む 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固有の”CreateTable”文を出力します。

>>> 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.TINYINTInteger に置き換えたい場合は、代わりにこのテーブルのデータ型を”ジェネリック化”するか、あるいは 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) )

MySQLの AUTO_INCREMENT ディレクティブは、PostgreSQLでは SERIAL 自動インクリメントデータ型を使用して最も厳密に表現されています。

New in version 1.4: TypeEngine.as_generic() メソッドが追加され、さらに DDLEvents.column_reflect() イベントの使用方法が改善され、 MetaData オブジェクトに適用できるようになりました。

Limitations of Reflection

重要なのは、リフレクションプロセスが Table メタデータを、リレーショナルデータベースで表現されている情報のみを使って再作成することです。このプロセスは、定義上、データベースに実際に格納されていないスキーマの側面を復元することはできません。リフレクションから利用できない状態には、次のものが含まれますが、これらに限定されません。

  • クライアント側のデフォルトで、Python関数かSQL式のいずれかで、Columndefault キーワードを使って定義されます(これは server_default とは別であることに注意してください。 server_default は具体的にはリフレクションを使って定義されます)。

  • 列情報、例えば Column.info 辞書に入れられた可能性のあるデータ

リレーショナルデータベースはまた、多くの場合、SQLAlchemyで指定されたものとは異なる形式でテーブルメタデータを報告します。リフレクションから返された Table オブジェクトは、元のPythonで定義された Table オブジェクトと同一のDDLを生成するために、常に信頼できるとは限りません。これが発生する領域には、サーバのデフォルト、列に関連付けられたシーケンス、制約やデータ型に関するさまざまな特異性が含まれます。サーバ側のデフォルトは、キャストディレクティブ(通常、PostgreSQLは ::<type> キャストを含みます)で返される場合もあれば、最初に指定されたものとは異なる引用パターンで返される場合もあります。

制限のもう1つのカテゴリーには、リフレクションが部分的にしか定義されていない、あるいはまだ定義されていないスキーマ構造があります。最近のリフレクションの改善により、ビュー、索引、外部キー・オプションなどをリフレクションできるようになりました。この記事を書いている時点では、CHECK制約、テーブル・コメント、トリガーなどの構造はリフレクションされていません。