Flask Model Group-By DateTime字段

时间:2018-01-31 10:22:12

标签: python sqlalchemy

我有一个带有Model类Journey的烧瓶应用程序:

class Journey(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    origin_id = db.Column(db.Integer, db.ForeignKey('location.id'), nullable=False)
    destination_id = db.Column(db.Integer, db.ForeignKey('location.id'), nullable=False)
    departure_time = db.Column(db.DateTime, nullable=False)
    travel_duration = db.Column(db.Integer, nullable=False)

    origin = relationship("Location", foreign_keys=[origin_id])
    destination = relationship("Location", foreign_keys=[destination_id])

我想将所有在同一刻钟内发生的旅程分组,并获得他们旅行时间的平均值。我基本上需要按小时和季度进行分组。 这些小组看起来像这样:

第1组(第10小时第1小时)

  • 15.01.2018 10:00
  • 16.01.2018 10:07
  • 20.01.2018 10:14

第2组(第10小时第2季)

  • 17.01.2018 10:15
  • 16.01.2018 10:23
  • 20.01.2018 10:29

第3组(第10小时第3季)

  • 15.01.2018 10:30
  • 16.01.2018 10:37
  • 20.01.2018 10:44

第4组(第10小时第4季)

  • 15.01.2018 10:45
  • 16.01.2018 10:52
  • 20.01.2018 10:59

有没有办法根据字段departure_hour创建字段departure_quarterdeparture_time?这样我可以使用以下查询获得平均值:

db.session.query(Journey.departure_hour, Journey.departure_quarter,
         func.avg(Journey.travel_duration)).group_by(Journey.departure_hour,
Journey.departure_quarter).all()

或者有不同的解决方案吗?

1 个答案:

答案 0 :(得分:1)

如果您的数据库或SQLAlchemy方言支持,您可以使用EXTRACT表达式提取相关字段。 hybrid property是隐藏所有内容的好方法:

from sqlalchemy.ext.hybrid import hybrid_property

class Journey(db.Model):                                           
    id = db.Column(db.Integer, primary_key=True)                               
    origin_id = db.Column(db.Integer, db.ForeignKey('location.id'), nullable=False)
    destination_id = db.Column(db.Integer, db.ForeignKey('location.id'), nullable=False)
    departure_time = db.Column(db.DateTime, nullable=False)
    travel_duration = db.Column(db.Integer, nullable=False)

    origin = relationship("Location", foreign_keys=[origin_id])
    destination = relationship("Location", foreign_keys=[destination_id])

    @hybrid_property                  
    def departure_hour(self):
        return self.departure_time.hour

    @departure_hour.expression
    def departure_hour(cls):
        return db.func.extract('hour', cls.departure_time).cast(db.Integer)

    @staticmethod
    def _extract_quarter_hour(minute):
        # Rounds down to nearest quarter, alternatively
        # floor(minute / 15) * 15
        return minute - minute % 15

    @hybrid_property
    def departure_quarter(self):
        return self._extract_quarter_hour(self.departure_time.minute)

    @departure_quarter.expression
    def departure_quarter(cls):
        minute = db.func.extract('minute', cls.departure_time).cast(db.Integer)
        return cls._extract_quarter_hour(minute)

有了这些,您的查询应该可以正常工作。