Skip to content

Reflection

Reflection即反射,他指示对象从已经存在的数据库中获取Schema。

一次性反射所有表

MetaData表示数据库,可以使用它来一次性反射其中的所以表:

Python
metadata_obj = MetaData()
# bind 是 Engine 或 Connection 对象
metadata_obj.reflect(bind=someengine)

users_table = metadata_obj.tables["users"]
addresses_table = metadata_obj.tables["addresses"]

如果需要从特定的模式(schema)反射所有表有两种方式:

Python
# 第一种方式,MetaData 中指定了 schema
metadata_obj = MetaData(schema="project")
metadata_obj.reflect(someengine)

# 第二种方式,reflect 中指定
metadata_obj = MetaData()
metadata_obj.reflect(someengine, schema="project")

单表反射

他们通过Table来进行:

Python
# autoload_with 指定 Engine 或 Connection 来进行放射
messages = Table("messages", metadata_obj, autoload_with=engine)

# 反射视图
my_view = Table("some_view", metadata, autoload_with=engine)

# 反射特定 schema 中的特定表
messages = Table("messages", metadata_obj, schema="project", autoload_with=someengine)

对于单表反射还能够进行覆盖操作:

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

Inspector

Inspector提供了更细粒度的反射:

Python
from sqlalchemy import create_engine
from sqlalchemy import inspect

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

我们持有 Inspector 对象来对整个数据库架构进行检查:

成员 说明
dialect 构建该 inspect 的后端
engine 构建该 inspect 的引擎
default_schema_name 默认的模式(schema)
get_indexes(table_name) 返回表索引
get_columns(table_name) 返回表列描述
get_table_names(schema) 返回表名,可以指定 schema 来指定特定模式的表
get_view_names() 返回视图名
get_schema() 返回模式名

映射类反射

对于Mapped Class同样可以使用反射。

基于 Table 的单表反射

Python
from sqlalchemy import create_engine
from sqlalchemy import Table
from sqlalchemy.orm import DeclarativeBase

engine = create_engine("postgresql+psycopg2://user:pass@hostname/my_existing_database")


class Base(DeclarativeBase):
    pass


class MyClass(Base):
    __table__ = Table(
        "mytable",
        Base.metadata,
        autoload_with=engine,
    )

基于 metadata 的一次性反射所有表

Python
from sqlalchemy import create_engine
from sqlalchemy import Table
from sqlalchemy.orm import DeclarativeBase

engine = create_engine("postgresql+psycopg2://user:pass@hostname/my_existing_database")


class Base(DeclarativeBase):
    pass


Base.metadata.reflect(engine)


class MyClass(Base):
    __table__ = Base.metadata.tables["mytable"]

限制

目前的反射实现不能反映 CHECK 约束、表注释和触发器等结构。