【前言】
sqlx简述
sqlx 是 rust 中的一个数据库访问工具。具有以下特点:
- 异步:原生就支持异步,在并发性高的场合能够得到更好的支持
- 编译时检查查询:sqlx可以在 cargo build 的时候检查执行sql和响应值
- 多数据库支持:PostgresSQL,MySql,SqlLite,MSSql,MariaDB
- 多运行时支持:支持主流 rust 运行时。async-std,tokio,actix,native-tls,rustls
- 内置连接池,支持查询缓存
注意:sqlx不是orm框架
【问题说明】
sqlx支持pg数据库的连接,当前开发环境使用rust sqlx来连接pg数据库,发现sqlx获取的时间为UTC时区
创表语句:
sqlx::query( r#" CREATE TABLE IF NOT EXISTS ticket ( id bigserial, name text, curtime timestamp default now() );"#, ) .execute(&pool) .await?; |
插入语句:
let row: (i64,) = sqlx::query_as("insert into ticket (name) values ($1) returning id") .bind("a new ticket") .fetch_one(&pool) .await?; |
查询结果:
【问题解决】
该问题的原因是由于sqlx底层连接数据库时默认会设置时区为UTC,在sqlx-0.6.2\sqlx-core\src\postgres\connection\establish.rs里添加UTC时区并在启动报文里携带发送给服务端,pg会读取GUC参数来设置UTC时区
let mut params = vec![ // Sets the display format for date and time values, // as well as the rules for interpreting ambiguous date input values. ("DateStyle", "ISO, MDY"), // Sets the client-side encoding (character set). // <https://www.postgresql.org/docs/devel/multibyte.html#MULTIBYTE-CHARSET-SUPPORTED> ("client_encoding", "UTF8"), // Sets the time zone for displaying and interpreting time stamps. ("TimeZone", "UTC"), ]; |
该问题解决可通过连接数据库后set直接设置时区解决
- 连接池:
设置连接池属性
let pool = PgPoolOptions::new() .after_connect(|conn, _meta| Box::pin(async move { conn.execute("SET TIME ZONE 'Asia/Shanghai';").await?; Ok(()) })) .max_connections(10) .connect("postgres://xxx@localhost:5432/postgres").await?; |
- 单个连接:
直接连接后通过sql设置时区
sqlx::query( r#" SET TIME ZONE 'Asia/Shanghai'; "#, ) .execute(&pool) .await?; |
修改后查询结果: