使用EXTRACT和AT TIME ZONE的SQLAlchemy ORM子句?

时间:2019-02-20 17:39:43

标签: python postgresql orm sqlalchemy

使用SQLAlchemy连接到Postgres数据库,我正在处理一个足球比赛表,该表看起来像这样:

CREATE TABLE game (
    id UUID PRIMARY KEY,
    date TIMESTAMP WITH TIME ZONE NOT NULL,
    ...
)

(实际上,实际上,还有更多列,所有这些列都与当前问题无关。)

我正在建立一个查询,使我可以提取在一周的指定天(或几天)内发生的所有游戏。由于时间戳记存储在UTC中,因此,如果我仅提取一周中的某天而不进行任何进一步的转换,则很多晚上的游戏都会记录为第二天的比赛。周一晚上7:00在丹佛进行的游戏将比UTC偏移-7小时,而EXTRACT(dow FROM date)将返回2(星期二)。此外,我目前不能保证每次查询时都会将数据库设置为美国时区。因此,如果我要在原始SQL中构造查询以返回星期一或星期四的所有游戏,我会这样做:

SELECT *
FROM game
WHERE EXTRACT(dow FROM game.date AT TIME ZONE 'America/Los_Angeles') IN (1, 4);

但是,我还没有找到使用SQLAlchemy ORM的一种优雅方法。只是EXTRACT子句的问题,我可以这样做:

from sqlalchemy import extract

days_of_week = [1, 4]
q = session.query(Game)
q = q.filter(extract('dow', Game.date).in_(days_of_week))
mon_thurs_games = q.all()

但是我们仍然需要偏移我们的时区,这就是我感到困惑的地方。我当前的解决方案有点笨拙,可以使用text()将上面的SQL子句放入ORM查询中,但是可以:

from sqlalchemy import text

days_of_week = [1, 4]
q_text = "EXTRACT(dow FROM game.date AT TIME ZONE 'America/Los_Angeles') IN :days"
q = session.query(Game)
q = q.filter(text(q_text).bindparams(days=tuple(days_of_week)))
mon_thurs_games = q.all()

这带给我一个问题:是否有一种方法可以正确利用SQLAlchemy ORM API?甚至是另一个更适合ORM方法的查询?我考虑过的几件事:

  1. 每次运行查询时,都使用session中的bind发送一个SET timezone TO 'America/Los_Angeles'命令,这样我就可以使用extract('dow', Game.date),(似乎效率不高)
  2. 在游戏表中添加一个day_of_week列(可以进行非常简单的查询,但对date来说是多余的)

任何/所有建议表示赞赏,谢谢!

0 个答案:

没有答案