Cat*_*155 6 python sqlite postgresql sqlalchemy python-3.x
我有一个叫做约会的模型,它的列datetime是一个DateTime字段,duration它是一个Integer字段,代表持续时间,以分钟为单位.现在我要检查,如果func.now()是与datetime任命和的总和datetime和duration
我目前正试图这样做,但我需要一个适用于PostgreSQL和SQLite的解决方案.
current_appointment = Appointment.query.filter(
Appointment.datetime.between(
func.now(),
func.timestampadd(
'MINUTES', Appointment.duration, func.now()
)
)
).limit(1).one_or_none()
Run Code Online (Sandbox Code Playgroud)
小智 3
我认为您无法直接在 sqlite 和 postgres 的 ORM 中执行此操作,但 sqlalchemy 允许您使用Custom SQL Constructs 和 Compilation Extension以跨方言的方式扩展它。
这段代码可能并不完全正确,因为我用一些不同的模型对其进行了破解,并将其翻译过来,但我得到了一些非常接近的内容来正确渲染 postgres SQL:
from sqlalchemy import func
from sqlalchemy.sql import expression
from sqlalchemy.types import DateTime
from sqlalchemy.ext.compiler import compiles
class durationnow(expression.FunctionElement):
type = DateTime()
name = 'durationnow'
@compiles(durationnow, 'sqlite')
def sl_durationnow(element, compiler, **kw):
return compiler.process(
func.timestampadd('MINUTES', element.clauses, func.now())
)
@compiles(durationnow, 'postgresql')
def pg_durationnow(element, compiler, **kw):
return compiler.process(
func.now() + func.make_interval(0, 0, 0, 0, 0, element.clauses)
)
# Or alternatively...
# return "now() - make_interval(0, 0, 0, 0, 0, {})".format(compiler.process(element.clauses))
# which is more in-line with how the documentation uses 'compiles'
Run Code Online (Sandbox Code Playgroud)
通过类似的设置,您应该能够将原始查询转换为跨方言查询,直接呈现为 SQL,而不是在 Python 中进行持续时间计算:
current_appointment = Appointment.query.filter(
Appointment.datetime.between(
func.now(),
durationnow(Appointment.duration)
).limit(1).one_or_none()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
232 次 |
| 最近记录: |