声明性扩展
特定于 Declarative 映射API。
在 1.4 版更改: 绝大多数声明性扩展现在集成到SQLAlchemy ORM中,并且可以从 sqlalchemy.orm
命名空间。请参阅上的文档 声明性映射 对于新文档。有关更改的概述,请参见 声明式现在集成到ORM中,具有新的特性 .
Object Name | Description |
---|---|
“concrete”声明性映射的助手类。 | |
“concrete”声明性映射的助手类。 | |
用于基于延迟反射步骤构造映射的助手类。 |
- class sqlalchemy.ext.declarative.AbstractConcreteBase¶
“concrete”声明性映射的助手类。
AbstractConcreteBase
将使用polymorphic_union()
自动对作为子类映射到此类的所有表执行函数。函数通过调用__declare_last__()
函数,它本质上是after_configured()
事件。AbstractConcreteBase
不会为基类生成一个映射类,但是它不会持久化到任何表;而是直接映射到可直接选择的“多态”类,并且只用于选择。比较ConcreteBase
,它确实为基类创建了持久化表。注解
这个
AbstractConcreteBase
类不打算为基类设置映射,除非定义了所有子类,因为它需要针对包含所有子类表的可选对象创建映射。为了实现这一点,它等待 映射器配置事件 此时,它会扫描所有已配置的子类,并设置一个映射,该映射将同时查询所有子类。当此事件通常自动调用时,
AbstractConcreteBase
,可能需要在 all 如果第一个操作是对这个基类的查询,则定义子类映射。为此,调用configure_mappers()
配置完所有所需的类后:from sqlalchemy.orm import configure_mappers configure_mappers()
参见
例子::
from sqlalchemy.ext.declarative import AbstractConcreteBase class Employee(AbstractConcreteBase, Base): pass class Manager(Employee): __tablename__ = 'manager' employee_id = Column(Integer, primary_key=True) name = Column(String(50)) manager_data = Column(String(40)) __mapper_args__ = { 'polymorphic_identity':'manager', 'concrete':True} configure_mappers()
抽象基类是由声明性的以特殊方式处理的;在类配置时,它的行为类似于声明性混合或
__abstract__
基类。一旦配置了类并生成了映射,它就会自己被映射,但在它的所有后代之后。这是一个非常独特的映射系统,在任何其他sqlacalchemy系统中都找不到。使用这种方法,我们可以指定将在映射的子类上发生的列和属性,就像我们通常在 混合和自定义基类 ::
class Company(Base): __tablename__ = 'company' id = Column(Integer, primary_key=True) class Employee(AbstractConcreteBase, Base): employee_id = Column(Integer, primary_key=True) @declared_attr def company_id(cls): return Column(ForeignKey('company.id')) @declared_attr def company(cls): return relationship("Company") class Manager(Employee): __tablename__ = 'manager' name = Column(String(50)) manager_data = Column(String(40)) __mapper_args__ = { 'polymorphic_identity':'manager', 'concrete':True} configure_mappers()
然而,当我们使用我们的映射时,两者都
Manager
和Employee
将具有独立可用的.company
属性:session.query(Employee).filter(Employee.company.has(id=5))
在 1.0.0 版更改: -力学
AbstractConcreteBase
已经被改写以支持直接建立在抽象基础上的关系,而没有任何特殊的构型步骤。参见
类签名
class
sqlalchemy.ext.declarative.AbstractConcreteBase
(sqlalchemy.ext.declarative.extensions.ConcreteBase
)
- class sqlalchemy.ext.declarative.ConcreteBase¶
“concrete”声明性映射的助手类。
ConcreteBase
将使用polymorphic_union()
自动对作为子类映射到此类的所有表执行函数。函数通过调用__declare_last__()
函数,它本质上是after_configured()
事件。ConcreteBase
为类本身生成映射表。比较AbstractConcreteBase
但事实并非如此。例子::
from sqlalchemy.ext.declarative import ConcreteBase class Employee(ConcreteBase, Base): __tablename__ = 'employee' employee_id = Column(Integer, primary_key=True) name = Column(String(50)) __mapper_args__ = { 'polymorphic_identity':'employee', 'concrete':True} class Manager(Employee): __tablename__ = 'manager' employee_id = Column(Integer, primary_key=True) name = Column(String(50)) manager_data = Column(String(40)) __mapper_args__ = { 'polymorphic_identity':'manager', 'concrete':True}
使用的鉴别器列的名称
polymorphic_union()
默认为名称type
. 已将一个名为suit的列映射到case中type
,可以通过设置_concrete_discriminator_name
属性:class Employee(ConcreteBase, Base): _concrete_discriminator_name = '_concrete_discriminator'
1.3.19 新版功能: 增加了
_concrete_discriminator_name
属性到ConcreteBase
以便可以自定义虚拟鉴别器列名。在 1.4.2 版更改: 这个
_concrete_discriminator_name
属性只需放在基类上即可对所有子类产生正确效果。现在,如果映射的列名与鉴别器名称冲突,则会引发一条显式错误消息,而在1.3.x系列中会出现一些警告,然后会生成一个无用的查询。参见
- class sqlalchemy.ext.declarative.DeferredReflection¶
用于基于延迟反射步骤构造映射的助手类。
通常,声明性可以与反射一起使用,方法是将
Table
使用autoload_with=engine作为__table__
属性添加到声明性类上。需要注意的是,Table
必须在构造普通声明性映射时完全反映,或者至少有一个主键列,这意味着Engine
必须在类声明时可用。这个
DeferredReflection
mixin将映射器的构造移动到后面的某个点,在调用一个首先反映所有Table
到目前为止创建的对象。类可以这样定义它:from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import DeferredReflection Base = declarative_base() class MyClass(DeferredReflection, Base): __tablename__ = 'mytable'
上面,
MyClass
尚未映射。在以上述方式定义了一系列类之后,可以使用prepare()
::engine = create_engine("someengine://...") DeferredReflection.prepare(engine)
这个
DeferredReflection
mixin可以应用于单个类,用作声明性基本身的基,或者用于自定义抽象类。使用抽象基只允许为特定的准备步骤准备类的子集,这对于使用多个引擎的应用程序是必需的。例如,如果一个应用程序有两个引擎,您可以使用两个基,并分别准备每个基,例如:class ReflectedOne(DeferredReflection, Base): __abstract__ = True class ReflectedTwo(DeferredReflection, Base): __abstract__ = True class MyClass(ReflectedOne): __tablename__ = 'mytable' class MyOtherClass(ReflectedOne): __tablename__ = 'myothertable' class YetAnotherClass(ReflectedTwo): __tablename__ = 'yetanothertable' # ... etc.
上面的类层次结构
ReflectedOne
和ReflectedTwo
可单独配置:ReflectedOne.prepare(engine_one) ReflectedTwo.prepare(engine_two)
- method
sqlalchemy.ext.declarative.DeferredReflection.
classmethod prepare(engine)¶ 反映一切
Table
所有当前对象DeferredReflection
子类
- method