【问题标题】:How to do arithmetic with timestamps and intervals in Rust Diesel如何在 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,
    }
}

我的问题:

  1. 我错了吗?这可以用没有自定义类型的柴油编写吗?
  2. 如果这不能用香草柴油编写,我如何将其分解为更安全、对柴油更友好的表达式?哪些部分是自定义的,我需要实现哪些特征?

【问题讨论】:

  • 是什么阻止你使用像diesel.rs/guides/getting-started这样的过滤方式?
  • @Stargateur 在我的应用程序的其余部分中,我有很多普通的柴油过滤器,但我不知道如何制作一个对时间戳和间隔进行算术运算的过滤器。

标签: rust rust-diesel


【解决方案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。我已经相应地编辑了答案。
猜你喜欢
  • 2010-10-25
  • 2017-10-31
  • 2018-02-18
  • 1970-01-01
  • 2014-08-09
  • 2016-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多