将 Timescale DB 的 Gapfill 与 JOOQ 一起使用会抛出参数:开始不能为 NULL
Using Timescale DB's Gapfill with JOOQ throws argument: start cannot be NULL
我有一个 Timescale DB 运行ning 并且正在使用 JOOQ 访问数据。
我正在使用 gapfill()
dslContext
.select(Routines.timeBucketGapfill5(
Routines.createInterval(DURATION), table.TIME, null, null).as(FieldName.TIME_BUCKET),
ifnull(count(table.STATUS), 0).as(FieldName.STATUS))
.from(table)
.where(table.ID.in(ids)
.and(table.TIME.ge(Timestamp.from(Instant.now().minus(Duration.ofSeconds(DURATION)))))
.and(table.TIME.le(Timestamp.from(Instant.now())))
.and(table.STATUS.eq(status)))
.groupBy(field(FieldName.TIME_BUCKET))
.fetch()
有时我得到一个
org.postgresql.util.PSQLException: ERROR: invalid time_bucket_gapfill argument: start cannot be NULL
Hinweis: You can either pass start and finish as arguments or in the WHERE clause
如果我总是有一个带有 greaterEquals 和 lessEquals 的 where 子句,start
怎么会是 NULL?
我能够记录 SQL 语句。如果我 运行 直接在数据库上查询它就可以正常工作。
select "public"."time_bucket_gapfill"("bucket_width" := cast("public"."create_interval"("seconds" := 43200) as "pg_catalog"."interval"), "ts" := cast("public"."device_health"."time" as timestamp), "start" := cast(null as timestamp), "finish" := cast(null as timestamp)) as "time_bucket", coalesce(count("public"."device_health"."health"), 0) as "health" from "public"."device_health" where ("public"."device_health"."device" in ('700004', '700009', '700008', '700005', '700007', '700000', '700003', '700001', '700002', '700006') and "public"."device_health"."time" >= timestamp '2020-03-11 13:59:20.0564238' and "public"."device_health"."time" <= timestamp '2020-03-25 13:59:20.0564238' and "public"."device_health"."health" = 'OK') group by time_bucket
如果您在 gapfill 调用中传入与 start
和 finish
可选参数相同的参数,您是否看到相同的错误?您能捕捉到 JOOQ 正在合成的实际 SQL 吗?
(此外,如需更多来回帮助,您可能会发现 slack.timescale.com 有帮助。)
为了解决这个问题,我现在将 start
和 finish
作为 JOOQ DSL.val()
以 Field<Timestamp>
的形式传递,并从中删除了 start/finish 部分条款。
我不知道究竟是什么导致了这个错误,但这修复了它。
这是工作代码:
var now = Instant.now();
Timestamp startTimestamp = Timestamp.from(now.minus(Duration.ofSeconds(DURATION)));
Timestamp finishTimestamp = Timestamp.from(now);
dslContext
.select(Routines.timeBucketGapfill5(
Routines.createInterval(DURATION),
table.TIME,
DSL.val(startTimestamp),
DSL.val(finishTimestamp))
.as(FieldName.TIME_BUCKET),
table.HEALTH,
ifnull(count(table.STATUS), 0).as(FieldName.STATUS))
.from(table)
.where(table.ID.in(ids))
.groupBy(field(FieldName.TIME_BUCKET))
.fetch();
我有一个 Timescale DB 运行ning 并且正在使用 JOOQ 访问数据。
我正在使用 gapfill()
dslContext
.select(Routines.timeBucketGapfill5(
Routines.createInterval(DURATION), table.TIME, null, null).as(FieldName.TIME_BUCKET),
ifnull(count(table.STATUS), 0).as(FieldName.STATUS))
.from(table)
.where(table.ID.in(ids)
.and(table.TIME.ge(Timestamp.from(Instant.now().minus(Duration.ofSeconds(DURATION)))))
.and(table.TIME.le(Timestamp.from(Instant.now())))
.and(table.STATUS.eq(status)))
.groupBy(field(FieldName.TIME_BUCKET))
.fetch()
有时我得到一个
org.postgresql.util.PSQLException: ERROR: invalid time_bucket_gapfill argument: start cannot be NULL
Hinweis: You can either pass start and finish as arguments or in the WHERE clause
如果我总是有一个带有 greaterEquals 和 lessEquals 的 where 子句,start
怎么会是 NULL?
我能够记录 SQL 语句。如果我 运行 直接在数据库上查询它就可以正常工作。
select "public"."time_bucket_gapfill"("bucket_width" := cast("public"."create_interval"("seconds" := 43200) as "pg_catalog"."interval"), "ts" := cast("public"."device_health"."time" as timestamp), "start" := cast(null as timestamp), "finish" := cast(null as timestamp)) as "time_bucket", coalesce(count("public"."device_health"."health"), 0) as "health" from "public"."device_health" where ("public"."device_health"."device" in ('700004', '700009', '700008', '700005', '700007', '700000', '700003', '700001', '700002', '700006') and "public"."device_health"."time" >= timestamp '2020-03-11 13:59:20.0564238' and "public"."device_health"."time" <= timestamp '2020-03-25 13:59:20.0564238' and "public"."device_health"."health" = 'OK') group by time_bucket
如果您在 gapfill 调用中传入与 start
和 finish
可选参数相同的参数,您是否看到相同的错误?您能捕捉到 JOOQ 正在合成的实际 SQL 吗?
(此外,如需更多来回帮助,您可能会发现 slack.timescale.com 有帮助。)
为了解决这个问题,我现在将 start
和 finish
作为 JOOQ DSL.val()
以 Field<Timestamp>
的形式传递,并从中删除了 start/finish 部分条款。
我不知道究竟是什么导致了这个错误,但这修复了它。
这是工作代码:
var now = Instant.now();
Timestamp startTimestamp = Timestamp.from(now.minus(Duration.ofSeconds(DURATION)));
Timestamp finishTimestamp = Timestamp.from(now);
dslContext
.select(Routines.timeBucketGapfill5(
Routines.createInterval(DURATION),
table.TIME,
DSL.val(startTimestamp),
DSL.val(finishTimestamp))
.as(FieldName.TIME_BUCKET),
table.HEALTH,
ifnull(count(table.STATUS), 0).as(FieldName.STATUS))
.from(table)
.where(table.ID.in(ids))
.groupBy(field(FieldName.TIME_BUCKET))
.fetch();