除名称、元数据和映射列参数之外的表参数是使用 __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__
为建立表元数据提供了一个更加集中的控制点,同时仍然获得了使用声明性的大部分好处。使用反射的应用程序可能希望在其他地方加载表元数据并将其传递给声明性类:
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类只是另一个语法块。下面通过使用 id
列中 primaryjoin
A的条件 relationship()
::
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
很容易设置 Table
使用的 autoload=True
与映射类一起使用:
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)