在SQLAlchemy中查找平均日期

时间:2018-09-20 21:41:40

标签: python sqlalchemy flask-sqlalchemy

我有两个桌子。 Foo和Bar。

class Foo(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  bars = db.relationship('Bar', backref='foo', lazy='dynamic')

class Bar(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  date = db.Column(db.DateTime, default=datetime.utcnow)
  foo_id= db.Column(db.Integer, db.ForeignKey('foo.id'))

如何在Foo中具有混合属性,该属性可以从所有条形图中找到平均日期。我尝试了以下方法,该方法不会产生任何错误,但不能给出预期的结果

@hybrid_property
  def baz(self):
    return db.select([db.func.avg(Bar.date)]) \
      .where(Bar.foo_id == self.id) \
      .label('baz')

我在做什么错了?

2 个答案:

答案 0 :(得分:1)

那是一个棘手的事情。

我不确定在avg()对象上应用DateTime是否很好。 如果我是你,我将以秒为单位计算该字段的平均值。 为此,您可以在hybrid_property中有一个expression和一个Bar,将date字段转换为秒:

class Bar(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  date = db.Column(db.DateTime)
  foo_id= db.Column(db.Integer, db.ForeignKey('foo.id'))

  @hybrid_property
  def date_seconds(self):
    return time.mktime(self.date.timetuple())

  @date_seconds.expression
  def date_seconds(cls):
    return time.mktime(cls.date.timetuple())

然后使用此date_seconds计算平均秒数,并将其转换回可读的时间格式。

答案 1 :(得分:1)

感谢question / answer

,我设法解决了问题

我做了一个自定义类型,自1970年1月1日起将日期时间存储为秒。(UTC)

class IntegerDate(types.TypeDecorator):
  impl = types.Integer

  def process_bind_param(self, value, dialect):
    return value.replace(tzinfo=timezone.utc).timestamp() * 1000

  def process_result_value(self, value, dialect):
    return datetime.utcfromtimestamp(value / 1000)

并将此date = db.Column(db.DateTime)更改为此date = db.Column(IntegerDate)

然后我可以得到平均值

@hybrid_property
  def baz(self):
    return db.select([db.func.avg(Bar.date)]) \
      .where(Bar.foo_id == self.id) \
      .label('baz')