SQLAlchemy将case语句映射到模型字段中

时间:2014-09-15 16:59:17

标签: python sqlalchemy

我正在尝试映射在使用case语句执行查询后得到的两个布尔值。 我的模型如下:

class Account(Base, SerializableMixin):
    __tablename__ = 'accounts'

    id = Column(Integer, primary_key=True)

    followers = relationship(
        'Account', secondary='followers_followees',
         primaryjoin=(FollowAssociation.followee_id == id),
         secondaryjoin=(FollowAssociation.follower_id == id),
         backref='followees')

class FollowAssociation(Base):
    __tablename__ = 'followers_followees'

    follower_id = Column(Integer, ForeignKey('accounts.id'), primary_key=True)
    followee_id = Column(Integer, ForeignKey('accounts.id'), primary_key=True)
    created_at = Column(DateTime, default=datetime.datetime.now)

我的查询如下:

with session_scope() as s:
    ali = aliased(FollowAssociation)
    s.query(Account, case([ (FollowAssociation.follower_id == None, False) ], else_=True),
        case([ (ali.follower_id == None, False) ], else_=True))\
     .outerjoin(FollowAssociation, and_(Account.id == FollowAssociation.followee_id, FollowAssociation.follower_id == 1))\
     .outerjoin(ali, and_(Account.id == ali.follower_id, ali.followee_id == 1)).all()

我得到的结果如下:      (<rsh.accounts.models.Account object at 0x7fe350477990>, False, False)

有没有办法映射这两个布尔值,表示我的模型中是否有另一个帐户?感谢

1 个答案:

答案 0 :(得分:0)

这在sqlalchemy中并不常见,但可能。有几种方法可以做到这一点。 其中之一是构建自定义映射器实例。

query = session.query(
    Account,
    case([(FollowAssociation.follower_id == None, False)], else_=True).label('first'),
    case([(ali.follower_id == None, False)], else_=True).label('second')
).outerjoin(
    FollowAssociation,
    and_(Account.id == FollowAssociation.followee_id, FollowAssociation.follower_id == 1)
).outerjoin(ali, and_(Account.id == ali.follower_id, ali.followee_id == 1))


class CustomAccount(object):
    pass


mapper(CustomAccount, query.statement.alias())

res = session.query(CustomAccount).all()
print(res[0].id)
print(res[0].first)

Here完整的例子。 其他可能的方法是使用hybrid_property