如何在 Rust Diesel 中使用时间戳和间隔进行算术运算
Posted
技术标签:
【中文标题】如何在 Rust Diesel 中使用时间戳和间隔进行算术运算【英文标题】:How to do arithmetic with timestamps and intervals in Rust Diesel 【发布时间】:2020-05-16 06:24:47 【问题描述】:我一直在尝试使用过滤器表达式构建柴油查询,这些表达式对时间戳和时间间隔进行算术和比较。我相信使用开箱即用的柴油无法编写以下表达式。不幸的是,我采用了使用sql(...)
函数的大锤方法:
let query = videos::table
.inner_join(events::table)
.filter(sql(r#""events"."start_date" <= NOW() + interval '60 seconds'"#))
.filter(sql(r#""events"."start_date" + ("videos"."duration" * interval '1 second') > NOW()"#))
我的(缩写)架构:
table!
events (id)
id -> Int4,
video_id -> Int4,
start_date -> Timestamp,
table!
videos (id)
id -> Int4,
duration -> Float4,
我的问题:
-
我错了吗?这可以用没有自定义类型的柴油编写吗?
如果这不能用香草柴油编写,我如何将其分解为更安全、对柴油更友好的表达式?哪些部分是自定义的,我需要实现哪些特征?
【问题讨论】:
是什么阻止你使用像diesel.rs/guides/getting-started这样的过滤方式? @Stargateur 在我的应用程序的其余部分中,我有很多普通的柴油过滤器,但我不知道如何制作一个对时间戳和间隔进行算术运算的过滤器。 【参考方案1】:我错了吗?这可以用没有自定义类型的柴油编写吗?
是的,这可以用柴油提供的方法和一些小的架构更改来编写。查看对应的documentation
Diesel 要求您只能在时间戳中添加/减去间隔。这意味着您需要您的架构来实现这一点:
table!
videos (id)
id -> Int4,
duration -> Interval,
你的查询是这样写的:
let query = videos::table
.inner_join(events::table)
.filter(events::start_date.le(now + 60.seconds()))
.filter(now.lt(events::start_date + videos::duration))
如果这不能用香草柴油编写,我如何将其分解为更安全、对柴油更友好的表达式?哪些部分是自定义的,我需要实现哪些特征?
理论上应该可以在柴油之外实施。该代码很可能与用于在柴油机中实现该代码的代码相同。可能您需要使用本地类型和更具体的实现。因此,如果您无法更改 videos::duration
的类型,那么沿着这条路线走下去可能是有意义的。
【讨论】:
哇,这看起来很棒。我将在今天晚些时候尝试并报告,谢谢! 第一个过滤器运行良好,但编译器抱怨第二个过滤器。我认为这部分:videos::duration * 1.second()
。也许我没有正确导入一些东西?错误是:the trait `diesel::Expression` is not implemented for `diesel::data_types::PgInterval`
你是对的,第二个过滤器不像我最初写的那样工作。问题是柴油说你不能用时间戳添加任意数字。你只能用间隔来做到这一点。这里最简单的解决方法是将videos::duration
的类型更改为Interval
而不是Float4
。我已经相应地编辑了答案。以上是关于如何在 Rust Diesel 中使用时间戳和间隔进行算术运算的主要内容,如果未能解决你的问题,请参考以下文章