SA:对于Date列,我可以拥有'年份'column_property吗?
问题描述:
我有一个在sqlalchemy-0.7中有Date列的类。我可以有一个column_property或类似的东西让我一年,让我轻松过滤它吗?我会如何写它?SA:对于Date列,我可以拥有'年份'column_property吗?
IE浏览器,我想有(声明语法):
class Foo(Base):
id = Column(Integer, primary_key=True)
date = Column(Date(), nullable=False)
year = column_property(something here)
# later on
q = session().query(Foo).filter_by(year=2011)
答
当然,你可以定义这样的属性:
year = column_property(extract('year', date))
但你真的需要它吗?您可以一年不通过重写过滤条件定义这样的属性过滤:
query(Foo).filter(extract('year', Foo.date)==2011)
更新
虽然这种解决方案看起来很简单它也有一个缺点:这样的条件在WHERE子句将永远不会对日使用指数领域。有很多排和高选择性的条件,这会对性能造成很大的影响。所以,你可能要重写的条件,这将导致RANGE索引扫描而不是全表扫描(如西蒙的意见建议):
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)
还可以使用一个 '标准' 的条件:'查询(美孚).filter(and_(Foo.date> =日期(2011年,1,1),Foo.date Simon 2011-04-05 12:23:54