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) 
+0

还可以使用一个 '标准' 的条件:'查询(美孚).filter(and_(Foo.date> =日期(2011年,1,1),Foo.date Simon 2011-04-05 12:23:54