【问题标题】:SqlAlchemy use PostgreSQL timestamptz "AT TIMEZONE" in queriesSqlAlchemy 在查询中使用 PostgreSQL timestamptz "AT TIMEZONE"
【发布时间】:2021-04-06 14:47:19
【问题描述】:

我有一个 PostgreSQL 11 表,其中有一列类型为 timestamp with timezone,我想在不同的时区显示这个时间。在纯 PL/pgSQL 中,我可以编写一个查询,例如

select id, creation_date at timezone 'America/New_York' from "Test" where id=1;

这将所有令人讨厌的时区处理留给数据库。 现在,如果我在 SqlAlchemy 中映射表(使用版本 1.4.5):

from sqlalchemy import select
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session

Base = declarative_base()

engine = create_engine("postgresql+psycopg2://user:pass@server/database")

class Test(Base):
    __tablename__ = "Test"
    id = Column(Integer, primary_key=True)
    creation_date = Column(DateTime(timezone=True))

我可以使用例如查询表

with Session(engine) as session:
    test = session.scalar(select(Test).where(Test.id==1))

但这给了我 test.creation_date 作为 UTC 中的 Python datetime 对象。当然,我可以运行此查询,然后在 Python 中转换时区,但是否可以告诉 SqlAlchemy 在选择时将at timezone 'America/New_York' 部分添加到Test.creation_date 列? 编辑: America/New_York 只是一个示例,必须为每个查询设置实际时区。

【问题讨论】:

  • 您是否总是希望 TZ 是 America/New_York?还是运行查询时需要配置?
  • 将为每个查询配置。为整个连接设置时区不会切断它。

标签: python postgresql sqlalchemy timestamp-with-timezone


【解决方案1】:

如果您需要为每个查询指定时区,并且根据postgresql: Date/Time Functions and Operators 的事实

函数timezone(zone, timestamp)等价于符合SQL的构造timestamp AT TIME ZONE zone。

以下解决方案应该适合您:

from sqlalchemy import func

expr = func.timezone('America/New_York', Test.creation_date)

test, in_ny = (
    session.query(
        Test,
        expr.label("in_ny"),
    ).filter(Test.id == 1)
).one()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 2019-05-18
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    相关资源
    最近更新 更多