Postgres重采样时间序列数据

时间:2018-08-19 18:09:10

标签: postgresql sqlalchemy time-series

我有以1分钟为增量存储在Postgres中的股票的OHLCV数据。

我正在尝试以5分钟为间隔重新采样数据。我已使用此answer生成以下SQL查询。

这是生成的SQL查询:

SELECT 
avg('open') AS open, 
avg('high') AS high, 
avg('low') AS low, 
avg('close') AS close, 
avg('volume') AS volume, 
avg('open_interest') AS open_interest, 
to_timestamp(floor(EXTRACT(epoch FROM 'timestamp') / 300) * 300) AS interval_alias 
WHERE 'symbol'='IRFC-N8' GROUP BY interval_alias

我收到此错误:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) function avg(unknown) is not unique
LINE 1: SELECT avg('open') AS open, avg('high') AS high, avg('low') ...
               ^
HINT:  Could not choose a best candidate function. You might need to add explicit type casts.

你能告诉我哪里出了问题吗?

编辑1 :为更好地呈现而格式化的代码。

编辑2 :根据以下答案,我需要在avg函数的参数周围使用双引号。我正在使用sqlalchemy生成表达式,并且正在创建单引号的字符串。这是生成平均查询的代码部分:

    cols = list()
    cols.append(func.avg(self.p.open).label(self.p.open))
    cols.append(func.avg(self.p.high).label(self.p.high))
    cols.append(func.avg(self.p.low).label(self.p.low))
    cols.append(func.avg(self.p.close).label(self.p.close))
    cols.append(func.avg(self.p.volume).label(self.p.volume))
    cols.append(func.avg(self.p.openinterest).label(self.p.openinterest))
    seconds = self._get_seconds()
    cols.append(func.to_timestamp(func.floor(func.extract("epoch", "timestamp") / seconds) * seconds).label("interval_alias"))

SqlAlchemy应该更好地了解使用双引号,但是会生成单引号。

1 个答案:

答案 0 :(得分:1)

db<>fiddle

您的错误是在您的'调用中使用单引号"而不是双引号AVG()。单引号标记文本,但您要为平均值命名列。因此,您需要双引号或可以保留双引号(这两种变体都显示在数据库小提琴中)。

编辑(真正的问题): 看来self.p.columnname仅给出了列的名称,而不是列本身。在SQLAlchemy上,对特定列的引用是table.c.columnname,用于引用特定列。请使用p代替c

注意: 如果平均所有数据,则可能会丢失重要的数据,即实际的最小值和最大值。您可能希望与其他功能聚合为MINMAX。也许WITHIN GROUP函数可以为您提供帮助。

https://www.postgresql.org/docs/current/static/functions-aggregate.html

https://www.postgresql.org/docs/9.5/static/functions-aggregate.html#FUNCTIONS-ORDEREDSET-TABLE