В дополнение к ответам, предоставленным harmic
, есть еще две возможности для решения этой проблемы.
Дизель обеспечивает простой интерфейс определить узлы запроса ast для sql функций, которые не предоставляются самим дизелем. Пользователям рекомендуется использовать эту функцию для самостоятельного определения отсутствующих функций. (Фактически дизель использует один и тот же метод для определения узлов запросов ast для sql функций, предоставляемых из коробки). Определенный узел запроса может использоваться в любом контексте, где допустимы типы его выражения, поэтому его можно использовать в предложениях select и where. (Это в основном типобезопасная версия вышеупомянутого решения sql)
Для данного вопроса должно работать что-то подобное:
#[derive(Queryable)]
pub struct Sales {
pub id: i32,
pub product_id: Option<i32>,
pub amount: Option<BigDecimal>,
pub date_sale: Option<String>,
}
sql_function! {
fn to_char(Nullable<Timestamp>, Text) -> Nullable<Text>;
}
let product_id = 1;
sales::table
.inner_join(product::table)
.select((
product::description,
sales::amount,
to_char(sales::date_sale, "dd/mm/YYYY")
))
.filter(sales::product_id.eq(product_id))
.load(&diesel::PgConnection);
Дизель Queryable
производная обеспечивает способ применения определенных типов манипуляций во время загрузки через пользовательский атрибут. В сочетании с решением chrono
, предоставленным harmic
, это дает следующий вариант:
#[derive(Queryable)]
pub struct Sales {
pub id: i32,
pub product_id: Option<i32>,
pub amount: Option<BigDecimal>,
#[diesel(deserialize_as = "MyChronoTypeLoader")]
pub date_sale: Option<String>
}
struct MyChronoTypeLoader(Option<String>);
impl Into<Option<String>> for MyChronoTypeLoader {
fn into(self) -> String {
self.0
}
}
impl<DB, ST> Queryable<ST, DB> for MyChronoTypeLoader
where
DB: Backend,
Option<NaiveDateTime>: Queryable<ST, DB>,
{
type Row = <Option<NaiveDateTime> as Queryable<ST, DB>>::Row;
fn build(row: Self::Row) -> Self {
MyChronoTypeLoader(Option::<NaiveDateTime>::build(row).map(|d| d.format("%d/%m/%Y").to_string()))
}
}