声明性API¶

API引用

sqlalchemy.ext.declarative.declarative_base(bind=None, metadata=None, mapper=None, cls=<class 'object'>, name='Base', constructor=<function _declarative_constructor>, class_registry=None, metaclass=<class 'sqlalchemy.ext.declarative.api.DeclarativeMeta'>)

为声明性类定义构造一个基类。

新的基类将被赋予一个产生适当 Table 对象并使 mapper() 基于类和类的任何子类中声明性提供的信息进行调用。

参数
  • bind -- 可选的 Connectable ,将被分配 bind 属性 MetaData 实例。

  • metadata -- 可选的 MetaData 实例。所有 Table 由基的子类隐式声明的对象将共享此元数据。如果未提供元数据实例,则将创建元数据实例。这个 MetaData 实例将通过 metadata 生成的声明性基类的属性。

  • mapper -- 可选的可调用文件,默认为 mapper() . 将用于将子类映射到它们的表。

  • cls -- 默认为 object . 用作生成的声明性基类的基的类型。可以是类或类的元组。

  • name -- 默认为 Base . 生成的类的显示名称。定制这不是必需的,但可以提高回溯和调试的清晰度。

  • constructor -- 默认为 _declarative_constructor() ,一个 __init__ 分配的实现 * *声明字段和实例关系的Kwarg。如果 None 供应,没有 __init__ 将提供和施工将回落到 cls.__init__ 通过普通的Python语义。

  • class_registry -- 可选字典,当字符串名称用于标识 relationship() 以及其他。允许两个或多个声明性基类共享相同的类名注册表,以简化基间关系。

  • metaclass -- 默认为 DeclarativeMeta . 元类或 __metaclass__ 可兼容的可调用项,用作生成的声明性基类的元类型。

在 1.1 版更改: 如果 declarative_base.cls 是单个类(而不是元组),构造的基类将继承其docstring。

sqlalchemy.ext.declarative.as_declarative(**kw)

类修饰器 declarative_base() .

提供到的语法快捷方式 cls 参数发送到 declarative_base() ,允许将基类就地转换为“声明性”基::

from sqlalchemy.ext.declarative import as_declarative

@as_declarative()
class Base(object):
    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()
    id = Column(Integer, primary_key=True)

class MyMappedClass(Base):
    # ...

传递给的所有关键字参数 as_declarative() 被传给 declarative_base() .

class sqlalchemy.ext.declarative.declared_attr(fget, cascading=False)

基地: sqlalchemy.orm.base._MappedAttributebuiltins.property

将类级方法标记为表示映射属性或特殊声明性成员名称的定义。

@声明的属性将属性转换为类似标量的属性,可以从非实例化类调用该属性。声明性将用@declared attr特别标记的属性视为返回特定于映射或声明性表配置的构造。属性的名称是属性的非动态版本的名称。

@声明的属性通常不适用于mixin,用于定义要应用于类的不同实现者的关系:

class ProvidesUser(object):
    "A mixin that adds a 'user' relationship to classes."

    @declared_attr
    def user(self):
        return relationship("User")

它还可以应用于映射类,例如为继承提供“多态”方案:

class Employee(Base):
    id = Column(Integer, primary_key=True)
    type = Column(String(50), nullable=False)

    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()

    @declared_attr
    def __mapper_args__(cls):
        if cls.__name__ == 'Employee':
            return {
                    "polymorphic_on":cls.type,
                    "polymorphic_identity":"Employee"
            }
        else:
            return {"polymorphic_identity":cls.__name__}
cascading

马克A declared_attr 作为级联。

这是一个特殊的使用修饰符,它指示在映射的继承方案中,基于列或MapperProperty的声明属性应根据映射的子类进行明显配置。

警告

这个 declared_attr.cascading 修改器有几个限制:

  • only 适用于 declared_attr 关于声明性混合类和 __abstract__ 类;当直接用于映射类时,它当前没有任何效果。

  • only 适用于通常命名的属性,例如,不适用于任何特殊下划线属性,例如 __tablename__ . 在这些属性上 no 效果。

  • 当前的标志 不允许进一步覆盖 沿着类层次结构向下;如果子类试图重写该属性,将发出警告并跳过被重写的属性。这是一个希望在某个时刻得到解决的限制。

下面,myClass和mySubClass都将 id 已建立列对象:

class HasIdMixin(object):
    @declared_attr.cascading
    def id(cls):
        if has_inherited_table(cls):
            return Column(
                ForeignKey('myclass.id'), primary_key=True)
        else:
            return Column(Integer, primary_key=True)

class MyClass(HasIdMixin, Base):
    __tablename__ = 'myclass'
    # ...

class MySubClass(MyClass):
    ""
    # ...

上述配置的行为是 MySubClass 将引用它自己的 id 列和列 MyClass 在名为的属性下 some_id .

sqlalchemy.ext.declarative.api._declarative_constructor(self, **kwargs)

允许从Kwargs初始化的简单构造函数。

使用中的名称和值设置构造实例的属性 kwargs .

只允许作为实例类的属性存在的键。例如,这些可以是任何映射的列或关系。

sqlalchemy.ext.declarative.has_inherited_table(cls)

给定一个类,如果它继承的任何类具有映射表,则返回true,否则返回false。

这在声明性混合中用于构建属性,这些属性的行为与继承层次结构中的子类不同。

sqlalchemy.ext.declarative.synonym_for(name, map_column=False)

产生一个 orm.synonym() 属性与Python描述符结合使用。

正在修饰的函数传递给 orm.synonym() 作为 orm.synonym.descriptor 参数::

class MyClass(Base):
    __tablename__ = 'my_table'

    id = Column(Integer, primary_key=True)
    _job_status = Column("job_status", String(50))

    @synonym_for("job_status")
    @property
    def job_status(self):
        return "Status: %s" % self._job_status

这个 hybrid properties SQLAlchemy的特性通常是首选的,而不是同义词,这是一个更传统的特性。

参见

同义词 -同义词概述

orm.synonym() -映射器级别函数

使用描述符和混合 -混合属性扩展提供了一种比同义词更灵活地增强属性行为的更新方法。

sqlalchemy.ext.declarative.comparable_using(comparator_factory)

decorator,允许在查询条件中使用python@property。

这是一个装饰的前端 comparable_property() 通过比较器工厂和被修饰的函数:

@comparable_using(MyComparatorType)
@property
def prop(self):
    return 'special sauce'

规则的 comparable_property() 也可以直接在声明性设置中使用,并且可以方便地读取/写入属性:

prop = comparable_property(MyComparatorType)
sqlalchemy.ext.declarative.instrument_declarative(cls, registry, metadata)

给定一个类,使用给定的注册表(可以是任何字典)和元数据对象以声明方式配置该类。

class sqlalchemy.ext.declarative.AbstractConcreteBase

基地: sqlalchemy.ext.declarative.api.ConcreteBase

“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__ 基类。一旦配置了类并生成了映射,它就会自己被映射,但在它的所有后代之后。这是一个非常独特的映射系统,在任何其他SQLAlchemy系统中都找不到。

使用这种方法,我们可以指定将在映射的子类上发生的列和属性,就像我们通常在 混合和自定义基类 ::

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

然而,当我们使用我们的映射时,两者都 ManagerEmployee 将具有独立可用的 .company 属性:

session.query(Employee).filter(Employee.company.has(id=5))

在 1.0.0 版更改: -力学 AbstractConcreteBase 已经被改写以支持直接建立在抽象基础上的关系,而没有任何特殊的构型步骤。

参见

ConcreteBase

具体的表继承

inheritance_concrete_helpers

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}

参见

AbstractConcreteBase

具体的表继承

inheritance_concrete_helpers

class sqlalchemy.ext.declarative.DeferredReflection

用于基于延迟反射步骤构造映射的助手类。

通常,声明性可以通过设置 Table 对象使用autoload=true作为 __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.

上面的类层次结构 ReflectedOneReflectedTwo 可单独配置:

ReflectedOne.prepare(engine_one)
ReflectedTwo.prepare(engine_two)
classmethod prepare(engine)

反映一切 Table 所有当前对象 DeferredReflection 子类

特别指示

__declare_last__()

这个 __declare_last__() 钩子允许定义类级函数,该函数由 MapperEvents.after_configured() 事件,在假定映射已完成且“配置”步骤已完成之后发生:

class MyClass(Base):
    @classmethod
    def __declare_last__(cls):
        ""
        # do something with mappings

__declare_first__()

喜欢 __declare_last__() ,但在映射器配置开始时通过 MapperEvents.before_configured() 事件:

class MyClass(Base):
    @classmethod
    def __declare_first__(cls):
        ""
        # do something before mappings are configured

0.9.3 新版功能.

__abstract__

__abstract__ 使声明性完全跳过类的表或映射器的生成。类可以以与mixin相同的方式添加到层次结构中(请参见 混合和自定义基类 ,允许子类仅从特殊类扩展::

class SomeAbstractBase(Base):
    __abstract__ = True

    def some_helpful_method(self):
        ""

    @declared_attr
    def __mapper_args__(cls):
        return {"helpful mapper arguments":True}

class MyMappedClass(SomeAbstractBase):
    ""

一种可能的用途 __abstract__ 是使用一个 MetaData 对于不同的基础:

Base = declarative_base()

class DefaultBase(Base):
    __abstract__ = True
    metadata = MetaData()

class OtherBase(Base):
    __abstract__ = True
    metadata = MetaData()

上面,继承 DefaultBase 将使用一个 MetaData 作为表的注册表,以及继承 OtherBase 将使用另一个。然后可以在不同的数据库中创建表本身:

DefaultBase.metadata.create_all(some_engine)
OtherBase.metadata_create_all(some_other_engine)

__table_cls__

允许用于生成 Table 定制。这是一个非常开放的钩子,允许对 Table 那个在这里产生的:

class MyMixin(object):
    @classmethod
    def __table_cls__(cls, name, metadata, *arg, **kw):
        return Table(
            "my_" + name,
            metadata, *arg, **kw
        )

上面的混音会导致 Table 为包含前缀而生成的对象 "my_" ,后跟通常使用 __tablename__ 属性。

__table_cls__ 也支持返回的情况 None 这将导致类被视为单表继承而不是其子类。这在某些自定义方案中可能很有用,可以根据表本身的参数确定应该进行单表继承,例如,如果不存在主键,则将其定义为单继承::

class AutoTable(object):
    @declared_attr
    def __tablename__(cls):
        return cls.__name__

    @classmethod
    def __table_cls__(cls, *arg, **kw):
        for obj in arg[1:]:
            if (isinstance(obj, Column) and obj.primary_key) or \
                    isinstance(obj, PrimaryKeyConstraint):
                return Table(*arg, **kw)

        return None

class Person(AutoTable, Base):
    id = Column(Integer, primary_key=True)

class Employee(Person):
    employee_name = Column(String)

以上 Employee 类将作为单表继承映射到 Personemployee_name 列将被添加为 Person

1.0.0 新版功能.