確かにそのようなプロパティを定義できます:
year = column_property(extract('year', date))
でも、本当に必要ですか?フィルター条件を書き換えることで、そのようなプロパティを定義せずに年でフィルター処理できます。
query(Foo).filter(extract('year', Foo.date)==2011)
アップデート
このソリューションは単純に見えますが、欠点もあります。WHERE 句のこのような条件では、日付フィールドにインデックスが使用されません。行数が多く、条件の選択性が高いと、パフォーマンスに大きな影響を与えます。したがって、FULL TABLE SCAN の代わりに RANGE INDEX SCAN を引き起こす条件を書き直すことができます (Simon のコメントで提案されているように):
start = datetime.date(year, 1, 1)
end = datetime.date(year, 12, 31)
query(Foo).filter(Foo.date.between(start, end))
このような動作を持つプロパティを定義することも可能です。コンパレータを再定義するだけです:
class YearComparator(ColumnProperty.Comparator):
def __eq__(self, year):
if isinstance(year, int):
column = self.prop.columns[0].get_children()[0].expr
start = datetime.date(year, 1, 1)
end = datetime.date(year, 12, 31)
return column.between(start, end)
else:
# It can be a column or exression which we can't handle such way
return ColumnProperty.Comparator.__eq__(self, year)
# __lt__, __gt__ etc. are very similar to __eq__
def year_property(date_column, **kwargs):
kwargs.setdefault('comparator_factory', YearComparator)
return column_property(extract('year', date_column), **kwargs)
class Foo(Base):
__tablename__ = 'Foo'
id = Column(Integer, primary_key=True)
date = Column(Date, index=True)
year = year_property(date)