我有一个 django 项目,它存储一些设备的实时数据。对于这种方式,我使用了timescaledb,它适合时间序列,并且基于 postgres。 Timescale 提供了一些我需要使用的超函数(特别是
lttb
,用于对数据进行下采样)。
例如,这是我希望实现的查询之一:
SELECT time as timestamp, value as value, %s as device_id
FROM unnest((SELECT lttb(timestamp, value, %s)
FROM core_devicedata where device_id=%s and timestamp between %s and %s))
我可以通过以下方式获取此查询的结果作为原始查询集:
for data in DeviceData.objects.raw(query):
...
我已经尝试过使用 django 进行原始 sql 查询。他们工作。问题是它们不提供过滤和排序功能,因为它们不返回实际的查询集。相反,它们返回一个“原始查询集”。我想要实现的是运行如下查询仅使用 djagno orm 的功能。
SELECT time as timestamp, value as value, %s as device_id
FROM unnest((SELECT lttb(timestamp, value, %s)
有什么建议吗?如果 django orm 本身无法做到这一点,请帮我以这种方式编写一个模块化管理器方法吗?就像我应该能够仅在需要时进行过滤或订购。
select lttb(time,price,5)->unnest() from crypto_ticks where symbol = 'BTC/USD' and time > now() - interval '1 month';
?column?
------------------------------------
("2024-04-09 13:23:29+00",70431)
("2024-04-17 16:08:07+00",59714.9)
("2024-04-22 23:15:59+00",67228.5)
("2024-05-01 08:24:03+00",56534.5)
("2024-05-07 14:37:03+00",63190.8)
(5 rows)
现在,让我们包含该符号并按其分组。
tsdb=> select symbol, lttb(time,price,5)->unnest() from crypto_ticks where symbol = 'BTC/USD' and time > now() - interval '1 month' group by 1;
symbol | ?column?
---------+------------------------------------
BTC/USD | ("2024-04-09 13:23:29+00",70431)
BTC/USD | ("2024-04-17 16:08:07+00",59714.9)
BTC/USD | ("2024-04-22 23:15:59+00",67228.5)
BTC/USD | ("2024-05-01 08:24:03+00",56534.5)
BTC/USD | ("2024-05-07 14:37:38+00",63266.6)
(5 rows)
现在,让我们用
().*
解除值的嵌套
tsdb=> select symbol, (lttb(time,price,5)->unnest()).* from crypto_ticks where symbol = 'BTC/USD' and time > now() - interval '1 month' group by 1;
symbol | time | value
---------+------------------------+---------
BTC/USD | 2024-04-09 13:23:29+00 | 70431
BTC/USD | 2024-04-17 16:08:07+00 | 59714.9
BTC/USD | 2024-04-22 23:15:59+00 | 67228.5
BTC/USD | 2024-05-01 08:24:03+00 | 56534.5
BTC/USD | 2024-05-07 14:37:38+00 | 63266.6