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

SQLAlchemy 1.1文档

表格配置

Table arguments other than the name, metadata, and mapped Column arguments are specified using the __table_args__ class attribute. 该属性包含通常发送到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