2016-11-20 41 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)