テーブルをjoinした結果をモデルにmappingできる。

__table__にsqlalchemy.orm.joinした結果を代入すると、複数のテーブルをjoinした結果をmappingしたモデルが作れる。
(idのconflictを避けるためにorm.column_propertyを使うことが多い)

import sqlahelper
import sqlalchemy as sa
import sqlalchemy.orm as orm

Base = sqlahelper.get_base()
DBSession = sqlahelper.get_session()

person_skillset = sa.Table(
    "person_skill",Base.metadata,
    sa.Column("id",sa.Integer,primary_key=True),
    sa.Column("skill",sa.String(255)) #in real, this is foreignkey
    )

person_information = sa.Table(
    "person_info",Base.metadata,
    sa.Column("id",sa.Integer,primary_key=True),
    sa.Column("name",sa.String(255)),
    sa.Column("age",sa.Integer))

class Person(Base):
    __table__= orm.join(person_skillset,person_information, person_skillset.c.id==person_information.c.id)
    id = orm.column_property(person_skillset.c.id, person_information.c.id)

利用例

engine = sa.create_engine("sqlite://")
sqlahelper.add_engine(engine)
Base.metadata.create_all()

def _column_iter(model, obj):
    from sqlalchemy.sql.operators import ColumnOperators
    for k, v in model.__dict__.items():
        if isinstance(v, ColumnOperators):
            yield k, v, getattr(obj, k, None)

for k,f,v in _column_iter(Person,Person(name="foo",age=20,skill="fire")):
    print k,f,v

# name Person.name foo
# age Person.age 20
# skill Person.skill fire
# id Person.id None