fix(grid-rs): decode run_time / valid_time as NaiveDateTime
Elixir's Ecto :utc_datetime maps to Postgres TIMESTAMP WITHOUT TIME ZONE — Ecto's contract is that the value is UTC, but the column itself is naive. sqlx's DateTime<Utc> binds/reads as TIMESTAMPTZ, so the read failed with "mismatched types ... TIMESTAMPTZ is not compatible with SQL type TIMESTAMP". Read as NaiveDateTime and reattach UTC at the decode boundary, keeping the downstream DateTime<Utc> signature. Test bind goes the other direction — bind .naive_utc() against the TIMESTAMP column.
This commit is contained in:
parent
a40e2d1630
commit
2d67cf7611
1 changed files with 13 additions and 6 deletions
|
|
@ -7,7 +7,7 @@
|
|||
//! * On success: status=done, NOTIFY propagation_ready '<iso valid_time>'.
|
||||
//! * On failure: status=failed, error=<string>. An hourly cron reseeds.
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||
use sqlx::postgres::{PgNotification, PgPool, PgPoolOptions};
|
||||
use sqlx::Row;
|
||||
use std::time::Duration;
|
||||
|
|
@ -63,10 +63,16 @@ pub async fn claim_next(pool: &PgPool) -> Result<Option<ClaimedTask>, DbError> {
|
|||
};
|
||||
|
||||
let id: Uuid = row.try_get("id")?;
|
||||
let run_time: DateTime<Utc> = row.try_get("run_time")?;
|
||||
// Elixir writes run_time/valid_time via Ecto `:utc_datetime`, which
|
||||
// lands in Postgres as TIMESTAMP WITHOUT TIME ZONE (values are UTC
|
||||
// by Ecto contract). Read as NaiveDateTime and reattach UTC so the
|
||||
// rest of the worker can keep its DateTime<Utc> signature.
|
||||
let run_time_naive: NaiveDateTime = row.try_get("run_time")?;
|
||||
let run_time = DateTime::<Utc>::from_naive_utc_and_offset(run_time_naive, Utc);
|
||||
let forecast_hour: i32 = row.try_get("forecast_hour")?;
|
||||
let forecast_hour = forecast_hour as i16;
|
||||
let valid_time: DateTime<Utc> = row.try_get("valid_time")?;
|
||||
let valid_time_naive: NaiveDateTime = row.try_get("valid_time")?;
|
||||
let valid_time = DateTime::<Utc>::from_naive_utc_and_offset(valid_time_naive, Utc);
|
||||
let attempt: i32 = row.try_get("attempt")?;
|
||||
|
||||
sqlx::query(
|
||||
|
|
@ -177,7 +183,8 @@ mod tests {
|
|||
};
|
||||
let pool = connect(&url, 4).await.unwrap();
|
||||
|
||||
// Seed a unique fh>0 row.
|
||||
// Seed a unique fh>0 row. run_time/valid_time bind as
|
||||
// NaiveDateTime to match Ecto's :utc_datetime column type.
|
||||
let run_time = Utc::now();
|
||||
let fh: i16 = 7;
|
||||
let valid_time = run_time + chrono::Duration::hours(fh as i64);
|
||||
|
|
@ -187,9 +194,9 @@ mod tests {
|
|||
VALUES ($1, $2, $3, $4, 'queued', 0, NOW(), NOW())"#,
|
||||
)
|
||||
.bind(id)
|
||||
.bind(run_time)
|
||||
.bind(run_time.naive_utc())
|
||||
.bind(fh as i32)
|
||||
.bind(valid_time)
|
||||
.bind(valid_time.naive_utc())
|
||||
.execute(&pool)
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue