the trait `LoadConnection` is not implemented for `&diesel::PgConnection` - postgresql

I want to create a rest api with rust and can't make it work.
My relevant code so far:
In the main.rs:
#[actix_web::main]
async fn main() -> std::io::Result<()> {
// Loading .env into environment variable.
dotenv::dotenv().ok();
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
// set up database connection pool
let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL");
let manager = ConnectionManager::<PgConnection>::new(database_url);
let pool: DbPool = r2d2::Pool::builder()
.test_on_check_out(true)
.build(manager)
.expect("Could not build connection pool");
let port = std::env::var("PORT").expect("$PORT is not set.");
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(pool.clone()))
.wrap(middleware::Logger::default())
.route("/", web::get().to(|| async { "Actix REST API" }))
.service(handlers::common::houses::index)
})
.bind(("0.0.0.0", port.parse().unwrap()))?
.run()
.await
}
The schema:
diesel::table! {
houses (id) {
id -> Int4,
user_id -> Varchar,
street -> Varchar,
figure -> Varchar,
floor -> Varchar,
create_date -> Timestamp,
update_date -> Timestamp,
is_deleted -> Bool,
}
}
The model:
#[derive(Debug, Serialize, Deserialize, Queryable)]
pub struct House {
pub id: i32,
pub user_id: String,
pub street: String,
pub figure: String,
pub floor: String,
pub create_date: chrono::NaiveDateTime,
pub update_date: chrono::NaiveDateTime,
pub is_deleted: bool,
}
The handler:
#[get("/houses")]
async fn index(pool: web::Data<DbPool>) -> Result<HttpResponse, Error> {
let houses = web::block(move || {
let conn = &pool.get()?;
find_all(&conn)
})
.await?
.map_err(actix_web::error::ErrorInternalServerError)?;
Ok(HttpResponse::Ok().json(houses))
}
fn find_all(conn: &PgConnection) -> Result<Vec<House>, DbError> {
use crate::schemas::common::houses::houses::dsl::*;
let items =houses.load::<House>(&mut conn)?;
Ok(items)
}
The dependencies are:
[dependencies]
actix-web = "4"
chrono = { version = "0.4.19", features = ["serde"] }
diesel = { version = "2.0.3", features = ["postgres", "r2d2", "chrono"] }
dotenv = "0.15.0"
env_logger = "0.10.0"
serde = { version = "1.0.136", features = ["derive"] }
serde_json = "1.0"`
It keeps giving an error, and I don't understand why.
The error is:
`error[E0277]: the trait bound `&diesel::PgConnection: LoadConnection` is not satisfied src\handlers\common\houses.rs:25:37
| 25 | let items =houses.load::<House>(&mut conn)?;
| ---- -^^^^^^^^
| | | the trait `LoadConnection` is not implemented for `&diesel::PgConnection` help: consider removing the leading `&`-reference required by a bound introduced by this call
| note: required for `table` to implement `LoadQuery<'_, &diesel::PgConnection, House>` note: required by a bound in `diesel::RunQueryDsl::load`
I've seen a similar error with the diesel version 1.4, but I think that this version is different.
Plus I'm starting with rust and I'm a little lost in general at the moment.
I was hopping someone knows what the problem is and how to fix it.

PgConnection implements LoadConnection but &PgConnection does not (note the extra &).
Make conn mutable and pass as a mutable reference:
#[get("/houses")]
async fn index(pool: web::Data<DbPool>) -> Result<HttpResponse, Error> {
let houses = web::block(move || {
let mut conn = pool.get()?; // <------------
find_all(&mut conn) // <------------
})
.await?
.map_err(actix_web::error::ErrorInternalServerError)?;
Ok(HttpResponse::Ok().json(houses))
}
fn find_all(conn: &mut PgConnection) -> Result<Vec<House>, DbError> {
// ^^^ <------------
use crate::schemas::common::houses::houses::dsl::*;
let items = houses.load::<House>(conn)?; // <------------
Ok(items)
}

Related

How to access database connection from a Rocket's fairing?

I'm trying to use database connection from a Rocket's on_ignite fairing:
use sqlx::{ self, FromRow };
use rocket::fairing::{self, Fairing, Info, Kind};
use rocket::{Build, Rocket};
use crate::database::PostgresDb;
#[derive(FromRow)]
struct TableRow {
column_a: String,
column_b: String
}
#[rocket::async_trait]
impl Fairing for TableRow {
fn info(&self) -> Info {
Info {
name: "Cache table row",
kind: Kind::Ignite,
}
}
async fn on_ignite(&self, rocket: Rocket<Build>) -> fairing::Result {
let mut db = rocket
.state::<Connection<PostgresDb>>()
.expect("Unable to find db connection.");
let row = sqlx::query_as::<_, TableRow>("SELECT * FROM table WHERE id = 1;")
.fetch_one(&mut db)
.await
.unwrap();
fairing::Result::Ok(rocket.manage(row))
}
}
The problem is I get following rust error during .fetch_one(&mut db):
the trait bound `&mut rocket_db_pools::Connection<PostgresDb>: Executor<'_>` is not satisfied
the following other types implement trait `Executor<'c>`:
<&'c mut PgConnection as Executor<'c>>
<&'c mut PgListener as Executor<'c>>
<&'c mut PoolConnection<Postgres> as Executor<'c>>
<&'t mut Transaction<'c, Postgres> as Executor<'t>>
<&sqlx::Pool<DB> as Executor<'p>>rustcClick for full compiler diagnostic
cache_rbac_on_ignite.rs(56, 14): required by a bound introduced by this call
query_as.rs(132, 17): required by a bound in `QueryAs::<'q, DB, O, A>::fetch_all`
I tried solution suggested here: How to get the database Connection in rocket.rs Fairing. but it did not work out.
Here is the code:
use sqlx::{ self, FromRow, Database };
use rocket::fairing::{self, Fairing, Info, Kind};
use rocket::{Build, Rocket};
use crate::database::PostgresDb;
#[derive(FromRow)]
struct TableRow {
column_a: String,
column_b: String
}
#[rocket::async_trait]
impl Fairing for TableRow {
fn info(&self) -> Info {
Info {
name: "Cache table row",
kind: Kind::Ignite,
}
}
async fn on_ignite(&self, rocket: Rocket<Build>) -> fairing::Result {
let mut db = PostgresDb::get_one(rocket).await.unwrap();
let row = sqlx::query_as::<_, TableRow>("SELECT * FROM table WHERE id = 1;")
.fetch_one(&mut db)
.await
.unwrap();
fairing::Result::Ok(rocket.manage(row))
}
}
I get following rust error on line let mut db = PostgresDb::get_one(rocket).await.unwrap();:
no function or associated item named `get_one` found for struct `PostgresDb` in the current scope
function or associated item not found in `PostgresDb`rustcClick for full compiler diagnostic
mod.rs(8, 1): function or associated item `get_one` not found for this struct
What is the right way to use database connection inside of the fairing? Thank you!
Finally found an answer. Here is what worked for me:
use rocket::fairing::{self, Fairing, Info, Kind};
use rocket::{Build, Rocket};
use rocket_db_pools::{ sqlx::{ self, FromRow }, Database };
use crate::database::PostgresDb;
#[derive(FromRow)]
struct TableRow {
column_a: String,
column_b: String
}
#[rocket::async_trait]
impl Fairing for TableRow {
fn info(&self) -> Info {
Info {
name: "Cache table row",
kind: Kind::Ignite,
}
}
async fn on_ignite(&self, rocket: Rocket<Build>) -> fairing::Result {
let db = PostgresDb::fetch(&rocket).unwrap();
let mut conn = db.aquire().await.unwrap();
let row = sqlx::query_as::<_, TableRow>("SELECT * FROM table WHERE id = 1;")
.fetch_one(&mut conn)
.await
.unwrap();
fairing::Result::Ok(rocket.manage(row))
}
}

how to using rust diesel to do the full text query

I am trying to using diesel diesel = { version = "1.4.8", features = ["postgres","64-column-tables","chrono","serde_json"] } to do a full text query, this is the sql command look like:
SELECT * FROM article a WHERE to_tsvector('english', title) ## to_tsquery('english','Rate|Limiting')
how to using rust diesel to do this query? I am using the like right now and want to switch to full text search, this is the like query code main.rs look like:
#[macro_use]
extern crate diesel;
use diesel::{TextExpressionMethods, QueryDsl, RunQueryDsl};
use rust_wheel::config::db::config;
use crate::model::diesel::dict::dict_models::Article;
mod model;
fn main() {
use model::diesel::dict::dict_schema::article as article_table;
let connection = config::establish_connection();
let mut query = article_table::table.into_boxed::<diesel::pg::Pg>();
query = query.filter(article_table::title.like(format!("{}{}{}","%","demo","%")));
let query_result = query.load::<Article>(&connection);
}
and this is the schema files dict_schema.rs look like:
table! {
article (id) {
id -> Int8,
user_id -> Int8,
title -> Varchar,
author -> Varchar,
guid -> Varchar,
created_time -> Int8,
updated_time -> Int8,
link -> Nullable<Varchar>,
sub_source_id -> Int8,
cover_image -> Nullable<Varchar>,
channel_reputation -> Int4,
editor_pick -> Nullable<Int4>,
}
}
and this is the model files dict_models.rs look like:
// Generated by diesel_ext
#![allow(unused)]
#![allow(clippy::all)]
use std::io::Write;
use diesel::deserialize::FromSql;
use diesel::pg::Pg;
use diesel::serialize::{Output, ToSql};
use diesel::sql_types::Jsonb;
use rocket::serde::Serialize;
use serde::Deserialize;
use chrono::DateTime;
use chrono::Utc;
use crate::model::diesel::dict::dict_schema::*;
#[derive(Queryable,QueryableByName,Debug,Serialize,Deserialize,Default,Clone)]
#[table_name = "article"]
pub struct Article {
pub id: i64,
pub user_id: i64,
pub title: String,
pub author: String,
pub guid: String,
pub created_time: i64,
pub updated_time: i64,
pub link: Option<String>,
pub sub_source_id: i64,
pub cover_image: Option<String>,
pub channel_reputation: i32,
pub editor_pick: Option<i32>,
}
and this is the dependencies Cargo.toml look like:
[package]
name = "rust-learn"
version = "0.1.0"
edition = "2018"
[dependencies]
rocket = { version = "=0.5.0-rc.2", features = ["json"] }
serde = { version = "1.0.64", features = ["derive"] }
serde_json = "1.0.64"
serde_derive = "1.0"
# database
diesel = { version = "1.4.7", features = ["postgres","serde_json"] }
dotenv = "0.15.0"
jsonwebtoken = "7"
chrono = "0.4"
config = "0.11"
ring = "0.16.20"
md5 = "0.7.0"
data-encoding = "2.3.2"
diesel_full_text_search = "1.0.1"
bigdecimal = "0.3.0"
# reddwarf public component
rust_wheel = { git = "https://github.com/jiangxiaoqiang/rust_wheel.git" }
What shuld I do to change to like query to full text search query? I am searching from internet but no one talk about this issue. BTW: this is the cargo version:
➜ rust-learn git:(group-by) ✗ cargo version
cargo 1.62.0 (a748cf5a3 2022-06-08)
and this is the rust version:
➜ rust-learn git:(group-by) ✗ rustc --version
rustc 1.62.0 (a8314ef7d 2022-06-27)
any idea about this issue? what should i do to using the full text search in diesel?
I have tried to add the dependencies diesel_full_text_search = "1.0.1" and tweak the main.rs code like this:
#[macro_use]
extern crate diesel;
use diesel::{TextExpressionMethods, QueryDsl, RunQueryDsl};
use diesel_full_text_search::{to_tsquery, to_tsvector, TsQueryExtensions};
use rust_wheel::config::db::config;
use diesel_full_text_search::TsVectorExtensions;
use crate::model::diesel::dict::dict_models::Article;
mod model;
fn main() {
use model::diesel::dict::dict_schema::article as article_table;
let connection = config::establish_connection();
let mut query = article_table::table.into_boxed::<diesel::pg::Pg>();
let filter_title = "经济 文化";
let query_items: Vec<&str> = filter_title.trim().split_whitespace().collect();
let query_array = query_items.join(" & ");
let tsquery = to_tsquery(query_array);
let tsvector = to_tsvector("'dolphinzhcfg', title");
query = query.filter(&tsvector.matches(&tsquery));
let query_result = query.load::<Article>(&connection);
}
shows error:
mismatched types [E0308] expected `char`, found `&to_tsquery<String>`
what should I do to fixed this problem?
Checkout the following functions:
diesel_full_text_search::to_tsvector
diesel_full_text_search::to_tsquery
diesel_full_text_search::TsVectorExtensions::matches

DateTime<Utc> compiles but not DateTime<Local> querying a table with a column defined as timestamp with time zone

I have a postgresql-table with a column defined as timestamp with time zone. The table is mapped to this struct:
#[derive(Serialize, Queryable)]
pub struct Location {
pub publication_time: DateTime<Utc>,
pub id: i32,
pub name: String,
pub latitude: BigDecimal,
pub longitude: BigDecimal,
}
The schema have this definition:
table! {
locations {
publication_time -> Timestamptz,
id -> Integer,
name -> Text,
latitude -> Numeric,
longitude -> Numeric,
}
}
(partial) Cargo.toml:
serde = "1.0.125"
serde_json = "1.0.64"
serde_derive = "1.0.125"
diesel = { version = "1.4.6", features = ["postgres", "r2d2", "chrono", "numeric"] }
bigdecimal = { version = "0.1.0", features = ["serde"] }
chrono = { version = "0.4.19", features = ["serde"] }
The function that queries the database:
fn get_all_locations(pool: web::Data<Pool>) -> Result<Vec<Location>, diesel::result::Error> {
let conn = pool.get().unwrap();
let items = locations.load::<Location>(&conn)?;
Ok(items)
}
This is then serialized to a JSON-array using serde_json. The DateTime in the database is 2021-04-08 15:02:02.514+02. When DateTime is Utc the program compiles fine, but the DateTime shown in UTC like 2021-04-08T13:02:02.514Z. I changed publication_time to DateTime<Local> to retain the time zone information but then cargo build fails with:
error[E0277]: the trait bound `DateTime<Local>: FromSql<diesel::sql_types::Timestamptz, Pg>` is not satisfied
--> src/controller.rs:21:27
|
21 | let items = locations.load::<Location>(&conn)?;
| ^^^^ the trait `FromSql<diesel::sql_types::Timestamptz, Pg>` is not implemented for `DateTime<Local>`
|
= help: the following implementations were found:
<DateTime<Utc> as FromSql<diesel::sql_types::Timestamptz, Pg>>
= note: required because of the requirements on the impl of `diesel::Queryable<diesel::sql_types::Timestamptz, Pg>` for `DateTime<Local>`
= note: 2 redundant requirements hidden
= note: required because of the requirements on the impl of `diesel::Queryable<(diesel::sql_types::Timestamptz, diesel::sql_types::Integer, diesel::sql_types::Text, diesel::sql_types::Numeric, diesel::sql_types::Numeric), Pg>` for `models::Location`
= note: required because of the requirements on the impl of `LoadQuery<_, models::Location>` for `locations::table`
I have another program that insert to this table and this works and the only difference is derive(Deserialize, Insertable).
#[derive(Deserialize, Insertable)]
pub struct Location {
pub publication_time: DateTime<Local>,
pub id: i32,
pub name: String,
pub latitude: BigDecimal,
pub longitude: BigDecimal,
}
Mapping a Timestamptz field to a DateTime<Local> is not supported by diesel itself, as it only provides the corresponding impl for DateTime<Utc>.
You can work this around by using the #[diesel(deserialize_as = "…")] attribute on the corresponding field and providing your own deserialization wrapper:
#[derive(Serialize, Queryable)]
pub struct Location {
#[diesel(deserialize_as = "MyDateTimeWrapper")]
pub publication_time: DateTime<Local>,
pub id: i32,
pub name: String,
pub latitude: BigDecimal,
pub longitude: BigDecimal,
}
pub struct MyDatetimeWrapper(DateTime<Local>);
impl Into<DateTime<Local>> for MyDatetimeWrapper {
fn into(self) -> DateTime<Local> {
self.0
}
}
impl<DB, ST> Queryable<ST, DB> for MyDateTimeWrapper
where
DB: Backend,
DateTime<Utc>: Queryable<ST, DB>,
{
type Row = <DateTime<Utc> as Queryable<ST, DB>>::Row;
fn build(row: Self::Row) -> Self {
Self(<DateTime<Utc> as Queryable<ST, DB>>::build(row).with_timezone(&Local))
}
}

How to insert HashMap into PostgreSQL as JSON type?

contacts has a data structure as HashMap, I'm using PostgreSQL client -rust-postgres to insert contact's key and value into a table, then I want to select from the table. Below is what I tried so far. I need help with writing the right syntax.
use postgres::{Client, NoTls};
use std::collections::HashMap;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Client::connect("host=127.0.0.1 user=postgres", NoTls)?;
client.simple_query("
DROP TABLE
IF EXISTS following_relation;
")?;
client.simple_query("
CREATE TABLE following_relation (
id SERIAL NOT NULL PRIMARY KEY,
relation JSON NOT NULL
)
")?;
let mut contacts = HashMap::new();
let mut v: Vec<String> = Vec::new();
v = vec!["jump".to_owned(), "jog".to_string()];
contacts.insert("Ashley", v.clone());
for (name, hobby) in contacts.iter() {
// 1. How to write sql statement with parameters?
client.execute(
"INSERT INTO following_relation(relation)
VALUE ('{"name" : $1, "hobby" : $2}')",
&[&name, &hobby],
)?;
}
for row in client.query("SELECT id, relation FROM following_relation", &[])? {
// 2. How to read from parse the result?
let id: i32 = row.get(0);
let relation = row.get(1);
//println!("found person: {} {} {:?}", id, relation["name"], relation["hobby"]);
}
Ok(())
}
I've been given the hints
Like the error message says, your query has VALUE but it needs to be VALUES.
Query parameters cannot be interpolated into strings. You should build the object in Rust, and use https://docs.rs/postgres/0.17.0/postgres/types/struct.Json.html to wrap the types when inserting.
I have no idea how to apply pub struct Json<T>(pub T); here.
How to build the query required in function execute?
pub fn execute<T: ?Sized>(
&mut self,
query: &T,
params: &[&(dyn ToSql + Sync)]
) -> Result<u64, Error>
where
T: ToStatement,
UPDATED, I tried with a more brief code sample
use postgres::{Client, NoTls};
use postgres::types::Json;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct relations {
name : String,
hobby: Vec<String>
}
pub struct Json<T>(pub T);
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Client::connect("host=127.0.0.1 user=postgres", NoTls)?;
client.simple_query("
DROP TABLE
IF EXISTS following_relation;
")?;
client.simple_query("
CREATE TABLE following_relation (
id SERIAL PRIMARY KEY,
relation JSON NOT NULL
)
")?;
let rel = relations {
name: "czfzdxx".to_string(),
hobby: vec![
"basketball".to_string(),
"jogging".to_string()
],
};
client.execute(
r#"INSERT INTO following_relation(relation)
VALUE ($1)"#,
&[&Json(&rel)]
)?;
Ok(())
}
I get
error[E0432]: unresolved import `postgres::types::Json`
You want Rust raw string literal:
for (name, hobby) in contacts.iter() {
client.execute(
r#"INSERT INTO following_relation(relation)
VALUE ('{"name" : ($1), "hobby" : ($2)}')"#,
&[&name, &following],
)?;
}
Between the start r#" and the end "#, your string literals can have any character except # itself without escaping. If you also want # itself, then starts the raw string literals with multiple #s and ends with matching number of #s.
Here is main.rs:
use postgres::{Client, NoTls};
use serde::{Deserialize, Serialize};
use postgres_types::Json;
use postgres_types::{FromSql};
#[derive(Debug, Deserialize, Serialize, FromSql)]
struct Relation {
name : String,
hobby: Vec<String>
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Client::connect("host=127.0.0.1 user=postgres", NoTls)?;
client.simple_query("
DROP TABLE
IF EXISTS following_relation;
")?;
client.simple_query("
CREATE TABLE following_relation (
id SERIAL PRIMARY KEY,
relation JSON NOT NULL
)
")?;
let rel = Relation {
name: "czfzdxx".to_string(),
hobby: vec![
"basketball".to_string(),
"jogging".to_string()
],
};
client.execute(
"INSERT INTO following_relation (relation) VALUES ($1)",
&[&Json::<Relation>(rel)]
)?;
for row in &client.query("SELECT relation FROM following_relation", &[]).unwrap() {
let rel: Json<Relation> = row.get(0);
println!("{:?}", rel);
}
Ok(())
}
and Cargo.toml:
[package]
name = "testapp"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
postgres = {version = "0.17.0"}
tokio-postgres = "0.5.1"
serde = {version = "1.0.104", features = ["derive"]}
postgres-types = {version = "0.1.0", features = ["derive", "with-serde_json-1"]}
serde_json = "1.0.45"
And here is the relevant documentation used: postgres_types and postgres. Search for serde_json, ToSql and FromSql traits are implemented for this third-party type.

How can I read a timestamp with timezone (timestamptz) value from PostgreSQL in Rust?

What's the right Rust data type to use for a timestamptz when using postgres version 0.17.0 with Rust 1.40.0?
I read the docs for Timestamp but have no idea what this means or how to implement it.
The readme for 0.17.0-alpha.1 has a table which says that timezone corresponds to Rust types time::Timespec or chrono::DateTime<Utc> but neither works for me.
When I try to use the stipulated features in my Cargo.toml using:
[dependencies]
postgres = {version="0.17.0-alpha.1", features=["with-chrono", "with-time"]}
I get this error:
the package `mypackage` depends on `postgres`, with features: `with-time, with-chrono` but `postgres` does not have these features.
Here's some functional code and corresponding dependencies. I want to be able to read and print the timezone per row (commented out)
main.rs
use postgres::{Client, Error, NoTls};
extern crate chrono;
use chrono::{DateTime, Local, NaiveDateTime, TimeZone, Utc};
extern crate time;
use time::Timespec;
pub fn main() -> Result<(), Error> {
let mut client = Client::connect("host=localhost user=postgres", NoTls)?;
client.simple_query(
"
CREATE TABLE mytable (
name text NOT NULL,
timestamp timestamptz NOT NULL)",
)?;
client.execute("INSERT INTO mytable VALUES ('bob', now());", &[])?;
for row in client.query("SELECT * FROM mytable", &[])? {
let name: &str = row.get(0);
// let timestamp: chrono::DateTime<Utc> = row.get(1); //doesnt work
// let timestamp: Timespec = row.get(1); //doesnt work
println!("name: {}", name);
// println!("timestamp: {}", timestamp);
}
Ok(())
}
Uncommenting
let timestamp: Timespec = row.get(1); //doesnt work
error[E0277]: the trait bound `time::Timespec: postgres_types::FromSql<'_>` is not satisfied
--> src/main.rs:30:39 | 30 |
let timestamp: Timespec = row.get(1); //doesnt work
^^^ the trait `postgres_types::FromSql<'_>` is not implemented for `time::Timespec`
Uncommenting
let timestamp: chrono::DateTime<Utc> = row.get(1); //doesnt work
error[E0277]: the trait bound `chrono::DateTime<chrono::Utc>: postgres_types::FromSql<'_>` is not satisfied
--> src/main.rs:29:52 29 |
let timestamp: chrono::DateTime<Utc> = row.get(1); //doesnt work
^^^ the trait `postgres_types::FromSql<'_>` is not implemented for `chrono::DateTime<chrono::Utc>`
Cargo.toml
[dependencies]
postgres = "0.17.0"
chrono = "0.4.10"
time = "0.1.14"
This link says to use time = "0.1.14". latest version also fails https://crates.io/crates/postgres/0.17.0-alpha.1
Once you know what features are available, it's reasonably direct to see that you need to use the with-chrono-0_4 feature.
use chrono::{DateTime, Utc}; // 0.4.10
use postgres::{Client, Error, NoTls}; // 0.17.0, features = ["with-chrono-0_4"]
pub fn main() -> Result<(), Error> {
let mut client = Client::connect("host=localhost user=stack-overflow", NoTls)?;
client.simple_query(
r#"
CREATE TABLE mytable (
name text NOT NULL,
timestamp timestamptz NOT NULL
)"#,
)?;
client.execute("INSERT INTO mytable VALUES ('bob', now());", &[])?;
for row in client.query("SELECT * FROM mytable", &[])? {
let name: &str = row.get(0);
let timestamp: DateTime<Utc> = row.get(1);
dbg!(name, timestamp);
}
Ok(())
}
[src/main.rs:20] name = "bob"
[src/main.rs:20] timestamp = 2020-01-16T01:21:58.755804Z
Thanks to https://github.com/sfackler/rust-postgres/issues/211, this works using version 0.15.0 of the postgres crate, but I'd like a solution using version 0.17.0.
main.rs
extern crate postgres;
use postgres::{Connection, TlsMode};
extern crate chrono;
use chrono::{DateTime, Local, NaiveDateTime, TimeZone, Utc};
fn main() {
let conn = Connection::connect("postgresql://postgres#localhost:5432", TlsMode::None).unwrap();
conn.execute(
"CREATE TABLE person (
name VARCHAR NOT NULL,
timestamp timestamptz
)",
&[],).unwrap();
conn.execute("INSERT INTO person VALUES ('bob', now());", &[]).unwrap();
for row in &conn.query("SELECT * FROM person", &[]).unwrap() {
let name: String = row.get(0);
let timestamp: chrono::DateTime<Utc> = row.get(1);
println!("name: {}", name);
println!("timestamp: {}", timestamp);
}
}
Output:
name: bob
timestamp: 2020-01-15 23:56:05.411304 UTC
Cargo.toml
[dependencies]
postgres = { version = "0.15", features = ["with-chrono"] }
chrono = "0.4.10"
time = "0.1.14"