Way*_*ner 14 python sqlalchemy null-coalescing-operator
或者我该如何使这个东西工作?
我有一个Interval对象:
class Interval(Base):
__tablename__ = 'intervals'
id = Column(Integer, primary_key=True)
start = Column(DateTime)
end = Column(DateTime, nullable=True)
task_id = Column(Integer, ForeignKey('tasks.id'))
@hybrid_property #used to just be @property
def hours_spent(self):
end = self.end or datetime.datetime.now()
return (end-start).total_seconds()/60/60
Run Code Online (Sandbox Code Playgroud)
一个任务:
class Task(Base):
__tablename__ = 'tasks'
id = Column(Integer, primary_key=True)
title = Column(String)
intervals = relationship("Interval", backref="task")
@hybrid_property # Also used to be just @property
def hours_spent(self):
return sum(i.hours_spent for i in self.intervals)
Run Code Online (Sandbox Code Playgroud)
当然,添加所有典型的设置代码.
现在,当我尝试做 session.query(Task).filter(Task.hours_spent > 3).all()
我NotImplementedError: <built-in function getitem>离开了sum(i.hours_spent....
所以我正在查看文档的这一部分,并且理论上可能有某种方式可以编写一些可以实现我想要的东西.这部分看起来也可能有用,我会在等待答案时看着它;)
Ste*_*rta 10
有关SQLAlchemy的coalesce函数的简单示例,这可能会有所帮助:在SQLAlchemy查询中处理空值 - 相当于isnull,nullif或coalesce.
以下是该帖子的几行代码:
from sqlalchemy.sql.functions import coalesce
my_config = session.query(Config).order_by(coalesce(Config.last_processed_at, datetime.date.min)).first()
Run Code Online (Sandbox Code Playgroud)
SQLAlchemy不够智能从这些操作数构建SQL表达式树,您必须使用显式propname.expression装饰器来提供它.但接下来又出现了另一个问题:没有可移植的方法将间隔转换为数据库中的小时数.你可以TIMEDIFF在MySQL,EXTRACT(EPOCH FROM ... ) / 3600PostgreSQL等中使用.我建议改变属性以返回timedelta,并将苹果与苹果进行比较.
from sqlalchemy import select, func
class Interval(Base):
...
@hybrid_property
def time_spent(self):
return (self.end or datetime.now()) - self.start
@time_spent.expression
def time_spent(cls):
return func.coalesce(cls.end, func.current_timestamp()) - cls.start
class Task(Base):
...
@hybrid_property
def time_spent(self):
return sum((i.time_spent for i in self.intervals), timedelta(0))
@time_spent.expression
def hours_spent(cls):
return (select([func.sum(Interval.time_spent)])
.where(cls.id==Interval.task_id)
.label('time_spent'))
Run Code Online (Sandbox Code Playgroud)
最后的查询是:
session.query(Task).filter(Task.time_spent > timedelta(hours=3)).all()
Run Code Online (Sandbox Code Playgroud)
转换为(在PostgreSQL后端):
SELECT task.id AS task_id, task.title AS task_title
FROM task
WHERE (SELECT sum(coalesce(interval."end", CURRENT_TIMESTAMP) - interval.start) AS sum_1
FROM interval
WHERE task.id = interval.task_id) > %(param_1)s
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10363 次 |
| 最近记录: |