2016-11-20 38 views
0

我在写一个非常基本的日记应用程序。我有以下的模型中的SQLAlchemy:在SQLAlchemy中总结日期差异

association_table = Table('association', Base.metadata, 
    Column('category_id', Integer, ForeignKey('category.id')), 
    Column('entry_id', Integer, ForeignKey('entry.id')) 
) 

class Category(Base): 
    __tablename__ = 'category' 

    id = Column(Integer, primary_key=True) 
    name = Column(String(100), unique=True) 
    entries = relationship('Entry', secondary=association_table, 
          back_populates='categories') 

class Entry(Base): 
    __tablename__ = 'entry' 

    id = Column(Integer, primary_key=True) 
    text = Column(String(200)) 
    started = Column(DateTime) 
    ended = Column(DateTime) 
    categories = relationship('Category', secondary=association_table, 
           back_populates='entries') 

我想获得标记与类别“工作”的所有条目,然后Entry.text组他们(这将是项目名称)。我基本上想看看我在每个项目上工作了多久。所以我写了如下:

from sqlalchemy.sql import func 
# s is the Session 
work = s.query(Category).filter(Category.name=='work').first() 
projects = (s.query(Entry.text, 
        func.sum(Entry.ended-Entry.started) 
         .label('duration')) 
       .filter(Entry.categories.contains(work)) 
       .group_by(Entry.text) 
       .order_by('duration desc')) 

这似乎应该工作;事实上,它确实当我运行它针对MySQL数据库直接:

>>> print str(projects) 
SELECT entry.text AS entry_text, sum(entry.ended - entry.started) AS duration 
FROM entry, association AS association_1 
WHERE entry.id = association_1.entry_id AND %(param_1)s = association_1.category_id 
GROUP BY entry.text ORDER BY duration desc 

然而,当我尝试运行此查询,我得到以下错误:

>>> projects.all() 
[...trace back...] 
TypeError: unsupported operand type(s) for -: 'Decimal' and 'datetime.datetime' 

我猜SA正试图做一些处理和失败?有没有办法让这个查询工作?

回答

0

似乎SQLAlchemy不能在数据库是MySQL时执行Interval(timedelta)算法。我能够得到它的工作:

class tsum(GenericFunction): 
    type = Float() 
    name = 'SUM' 

projects = s.query(Entry.text, (func.t_sum(
       func.time_to_sec(func.timediff(Entry.ended, Entry.started)/60) 
        .label('duration')) 
      .filter(Entry.categories.contains(work)) 
      .group_by(Entry.text) 
      .order_by('duration desc') 

其中返回的元组(text, minutes)