使用SQLAlchemy的动态列属性
我有一些SA模型,现在需要一些技巧:
class Entry(Base):
__tablename__ = 'entry'
id = Column(Integer, primary_key=True)
title = Column(Unicode(255))
author_id = Column(Integer, ForeignKey('user.id'))
date = Column(DateTime)
content = Column(Text)
author = relationship('User', backref='entries')
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
username = Column(Unicode(255))
...
如你所见,这个模型很常见,用户会写一些记录……我需要展示一些关于这些记录的统计信息(比如每周或每月的记录数量……)
为了计算记录数量,我在用户模型中添加了一个column_property,像这样:
class User(Base):
...
entries_count = column_property(select([func.count(Entry.id)]).\
where(Entry.author_id==id))
这样我就能显示用户写了多少条记录。但是为了根据日期范围生成一些统计数据,我需要动态调整entries_count,以便添加日期的条件。
所以问题是:你会怎么处理日期条件呢?使用column_property是否是满足这种需求的最佳方案呢?
提前谢谢你。
1 个回答
8
添加属性是一种获取与对象相关的数据库状态的好方法。但是,如果有外部的条件参数,那么这个计数就不仅仅是一个状态,而是一个函数。把这样的数据表示为对象的属性就不太合适了。所以,最好直接查询额外的数据(在下面的所有例子中,都是计算比start_date
更新的条目数量):
session.query(User, func.count(Entry.id))\
.outerjoin((Entry, (Entry.author_id==User.id) & (Entry.date>start_date)))\
.group_by(User.id)
或者在User
类中定义一个辅助方法(而不是属性!)来简化使用:
class User(Base):
# ...
@classmethod
def entries_count(cls, cond):
return select([func.count(Entry.id)])\
.where((Entry.author_id==cls.id) & cond)\
.as_scalar()
session.query(User, User.entries_count(Entry.date>start_date))