除了名称,元数据和映射列参数之外的表参数是使用__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}
)
作为__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
。