版本:1.1.0b2 |发布日期:2016年7月1日

SQLAlchemy 1.1文档

表格配置

除了名称,元数据和映射列参数之外的表参数是使用__table_args__类属性指定的。该属性包含通常发送到Table构造函数的位置和关键字参数。该属性可以用两种形式之一来指定。一个是字典:

class MyClass(Base):
    __tablename__ = 'sometable'
    __table_args__ = {'mysql_engine':'InnoDB'}

另一个是元组,每个参数都是位置的(通常是约束条件):

class MyClass(Base):
    __tablename__ = 'sometable'
    __table_args__ = (
            ForeignKeyConstraint(['id'], ['remote_table.id']),
            UniqueConstraint('foo'),
            )

通过将最后一个参数指定为字典,可以使用上述形式指定关键字参数:

class MyClass(Base):
    __tablename__ = 'sometable'
    __table_args__ = (
            ForeignKeyConstraint(['id'], ['remote_table.id']),
            UniqueConstraint('foo'),
            {'autoload':True}
            )

使用__table __ 的混合方法

作为__tablename__的替代方案,可以使用直接的Table结构。在这种情况下需要名称的Column对象将被添加到映射中,就像正常映射到表一样:

class MyClass(Base):
    __table__ = Table('my_table', Base.metadata,
        Column('id', Integer, primary_key=True),
        Column('name', String(50))
    )

__table__ provides a more focused point of control for establishing table metadata, while still getting most of the benefits of using declarative. 使用反射的应用程序可能希望在其他地方加载表元数据并将其传递给声明性类:

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
Base.metadata.reflect(some_engine)

class User(Base):
    __table__ = metadata.tables['user']

class Address(Base):
    __table__ = metadata.tables['address']

一些配置方案可能会发现使用__table__更合适,例如那些已经利用Table的数据驱动性质来自定义和/或自动化模式定义的配置方案。

请注意,当使用__table__方法时,该对象可立即用作类声明主体本身内的Table,因为Python类只是另一个语法块。relationship()primaryjoin条件中使用id列来说明以下情况:

class MyClass(Base):
    __table__ = Table('my_table', Base.metadata,
        Column('id', Integer, primary_key=True),
        Column('name', String(50))
    )

    widgets = relationship(Widget,
                primaryjoin=Widget.myclass_id==__table__.c.id)

类似地,引用__table__的映射属性可以内联放置,如下我们将name列分配给属性_name,生成同义词对于name

from sqlalchemy.ext.declarative import synonym_for

class MyClass(Base):
    __table__ = Table('my_table', Base.metadata,
        Column('id', Integer, primary_key=True),
        Column('name', String(50))
    )

    _name = __table__.c.name

    @synonym_for("_name")
    def name(self):
        return "Name: %s" % _name

用声明使用反射

autoload=True与映射类结合使用的Table很容易:

class MyClass(Base):
    __table__ = Table('mytable', Base.metadata,
                    autoload=True, autoload_with=some_engine)

然而,这里可以做出的一个改进是在首次声明类时不要求Engine可用。为了达到这个目的,使用DeferredReflection mixin,它只有在调用一个特殊的prepare(engine)步骤后才能设置映射:

from sqlalchemy.ext.declarative import declarative_base, DeferredReflection

Base = declarative_base(cls=DeferredReflection)

class Foo(Base):
    __tablename__ = 'foo'
    bars = relationship("Bar")

class Bar(Base):
    __tablename__ = 'bar'

    # illustrate overriding of "bar.foo_id" to have
    # a foreign key constraint otherwise not
    # reflected, such as when using MySQL
    foo_id = Column(Integer, ForeignKey('foo.id'))

Base.prepare(e)

版本0.8新增:新增DeferredReflection