Redshift:DateDiff 调用上的 SqlAlchemy 错误

Posted

技术标签:

【中文标题】Redshift:DateDiff 调用上的 SqlAlchemy 错误【英文标题】:Redshift: SqlAlchemy error on DateDiff call 【发布时间】:2016-11-02 19:40:40 【问题描述】:

我在调用 Redshift DATEDIFF 时不断收到错误消息。连接到同一个 Redshift 服务器时,我已成功使用 SQL Workbench。不幸的是,我使用 SQLAlchemy 并没有那么热,我希望我能在这里得到一些帮助。如果您需要更多详细信息,请告诉我。


类定义为MyTable

class MyTable(Base):
    __tablename__ = 'my_table'
    __table_args__ = 
        'schema': 'elm'
    
    tstamp = Column(TIMESTAMP(timezone=True), nullable=False)

我试图在 my_table 上查找最后 12 小时的 tstamps,其中的值比 12 小时 早于 >最新的 tstamp 值。 (datediff(hour, max(tstamp), tstamp) > 12)

# Get the most recent timestamp
max = session.execute(select([func.max(MyTable.tstamp)])).first()[0]

# Label the calculated column that will determine the difference
l = func.datediff('hour', max, MyTable.tstamp).label('z') # have also tried `text('hour')`

# Get the query
z = session.query(MyTable).filter(
    MyTable.tstamp.in_(
        select(
            [distinct(MyTable.tstamp), l]
        ).where(
            l >= 36
        )
    )
)

但是,我不断收到此错误:

sqlalchemy.exc.ProgrammingError: 
(psycopg2.ProgrammingError) 
function pg_catalog.date_diff("unknown", timestamp with time zone, timestamp with time zone) does not exist
HINT:  No function matches the given name and argument types. 
You may need to add explicit type casts.

当我打印到控制台时,这就是我的 SQL 的样子。将SQL Workbench 用于Redshift 服务器可以得到我期望的结果。

[SQL: '
    SELECT elm.my_table.tstamp AS elm_my_table_tstamp 
    FROM elm.my_table
    WHERE elm.my_table.tstamp IN (
        SELECT DISTINCT elm.my_table.tstamp, 
        datediff(%(datediff_1)s, %(datediff_2)s, elm.my_table.tstamp) AS z 
        FROM elm.my_table 
        WHERE datediff(%(datediff_1)s, %(datediff_2)s, elm.my_table.tstamp) >= %(param_1)s)
'] 
[
    parameters: 
    'datediff_2': datetime.datetime(2016, 11, 2, 19, 15, tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=0, name=None)), 
    'param_1': 12, 
    'datediff_1': 'hour'
    
]

进口:

from my_package import MyTable
from sqlalchemy import select, func, distinct, extract, text

结果:

max = session.execute(select([func.max(MyTable.tstamp)])).first()[0]
session.execute(MyTable.__table__.delete().where(
    MyTable.tstamp.in_(
        select([distinct(MyTable.tstamp)]).where(
            func.datediff('hour',
                          cast(MyTable.tstamp, TIMESTAMP(timezone=False)),
                          cast(max, TIMESTAMP(timezone=False)))
            >= 12
        )
    )
))

(我想删除找到的行)

【问题讨论】:

【参考方案1】:

DATEDIFF 不支持timestamptz 类型。 timestamptz 类型是最近添加到 Redshift 的。您需要将其转换为 timestamp,例如(未测试)

func.datediff("max", max.replace(tzinfo=None), cast(MyTable.tstamp, TIMESTAMP(timezone=False)))

【讨论】:

酷,所以CAST(tstamp, TIMESTAMP(timezone=False)) 消除了错误,但我仍然没有得到结果。 +1 寻求帮助,但我仍然需要解决问题 @J.D.我认为您正在使用 DATEDIFF 向后。 DATEDIFF(..., a, b) 给你b - a,而不是a - b 你说得对。 2/2。我可以给你两票吗?

以上是关于Redshift:DateDiff 调用上的 SqlAlchemy 错误的主要内容,如果未能解决你的问题,请参考以下文章

Postgres/Redshift DATEDIFF 转换为 FLOAT

将 DATEDIFF 从 SQL Server 转换为 redshift

如何使用 redshift 上的函数插入表格

PowerBI:根据 DATEDIFF 上的条件正确聚合度量

对本机函数“DATEDIFF”的调用中的参数计数不正确

表中行上的 SQL Server Datediff