我正在尝试将 Postgres 中的数组字段加载到 Rust 结构中,如下所示
use sqlx::{Pool, PgConnection, PgPool, FromRow};
use sqlx::postgres::PgQueryAs;
#[derive(Copy, Clone, sqlx::Type)]
#[sqlx(rename = "VARCHAR")]
#[sqlx(rename_all = "snake_case")]
enum Coupon {
ChristmasSaleCoupon,
NewYearSaleCoupon,
}
#[derive(FromRow, Clone)]
struct UserCouponMap {
pub id: i64,
pub user_id: i64,
pub coupons: Vec<Coupon>,
}
impl UserCouponMap {
pub async fn get_for_userid(db_pool: Pool<PgConnection>, user_id: i64) -> Vec<UserCouponMap> {
let user_coupon_map: Vec<UserCouponMap> = sqlx::query_as("SELECT * FROM user_coupon_map WHERE user_id = $1")
.bind(user_id)
.fetch_all(db_pool)
.await
.expect("failed to fetch user coupon map");
user_coupon_map
}
}
#[tokio::main] …Run Code Online (Sandbox Code Playgroud) 我目前正在使用actix-web和构建一个应用程序sqlx。我构建的架构与此源代码非常相似。
这基本上是包装数据库访问的特征,到目前为止一切顺利。但这假设每个方法都会从池中获取连接并执行它。无法共享事务工作流程的连接(例如,SELECT FOR UPDATE ... process ... UPDATE)。
我可以使用哪种架构或库来实现这一目标?
我使用sqlx与 Postgres 数据库进行通信。我试图用存储库模式抽象数据库通信。另外,通过这个抽象,我想使用工作单元模式在存储库之间共享数据库事务。我遇到的唯一问题是,如果没有明确提供参数(例如) ,我不知道如何sqlx在这些存储库之间共享事务。我想在(工作单元)抽象中创建和共享事务。transactionsaverepository_x.save(entity, transaction)uow
我想实现这样的目标
struct CommandHandler {
unit_of_work: UnitOfWork
}
impl CommandHandler {
pub fn handle(&self, &command: Command) {
let repository_a = self.unit_of_work.repository_a();
let repository_b = self.unit_of_work.repository_b();
let entity_a = repository_a.get_by_id(command.id);
let entity_b = repository_b.get_by_id(entity_a.id);
unit_of_work.start_transaction();
repository_a.save(entity_a);
repository_b.save(entity_b);
unit_of_work.commit_transaction();
}
}
Run Code Online (Sandbox Code Playgroud)
unit_of_work有谁知道执行上述示例的结构的实现是什么样的?
我想在 sqlx 中运行嵌套查询。这是我尝试过的:
sqlx::query_as!(NseData, "select * from nse_data where trading_day = (select max(trading_day) from nse_data)").fetch_one(&app_context.db_connection).await?;
Run Code Online (Sandbox Code Playgroud)
但它给了我以下错误......
error[E0658]: attributes on expressions are experimental
--> db/src/nse_data.rs:30:9
|
30 | sqlx::query_as!(NseData, "select * from nse_data where trading_day = (select max(trading_day) from nse_data)").await?
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
Run Code Online (Sandbox Code Playgroud) 在sqlx 中有一种Transaction类型可以让您在一个事务中运行多个查询。
我试图弄清楚如何做到这一点,遗憾的是没有记录,尽管有自动生成的 API 文档。
我的第一次尝试:
async fn insert_user() {
let pool: sqlx::Pool<sqlx::MySql> =
futures::executor::block_on(crate::db::open_mariadb_pool()).unwrap();
use sqlx::Acquire;
let mut conn = pool.acquire().await.unwrap();
let tx = conn.begin().await.unwrap();
let insert_query = sqlx::query("INSERT INTO user (email, email_verification_secret, email_verified, password_hash, hourly_rate)
VALUES (?, ?, ?, ?, ?);"
)
.bind("text@example.com")
.bind(false)
.bind(123)
.bind("pwhash")
.bind(20);
let get_row_query = sqlx::query::<sqlx::MySql>("SELECT * FROM user WHERE id = LAST_INSERT_ID();");
insert_query.execute(tx);
get_row_query.execute(tx);
tx.commit();
}
Run Code Online (Sandbox Code Playgroud)
产生以下错误:
error[E0277]: the trait bound `Transaction<'_, MySql>: Executor<'_>` is not satisfied
--> …Run Code Online (Sandbox Code Playgroud) 我有以下插入查询:
pub async fn create_property(
&self,
property: Property,
) -> Result<PropertyId, sqlx::Error> {
/* acquire connection from the pool */
let mut conn = self.pool.acquire().await?;
/* insert the property and retrieve its ID */
let id = sqlx::query(
r#"INSERT INTO properties (
address_unit_number,
address_street_number,
address_street,
address_suburb,
address_state,
address_postcode,
area,
property_type,
available,
num_bedrooms,
num_bathrooms,
num_garages
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12);"#)
.bind(property.address.unit_number)
.bind(property.address.street_number)
.bind(property.address.street)
.bind(property.address.suburb)
.bind(property.address.state)
.bind(property.address.postcode)
.bind(property.area)
.bind(property.property_type)
.bind(property.available)
.bind(property.num_bedrooms)
.bind(property.num_bathrooms)
.bind(property.num_garages) …Run Code Online (Sandbox Code Playgroud) 我有 2 个表(工作场所和工人),具有:m 关系。我的目标是拥有一个workplace包含Vec所有相关workers. 我想使用 sqlx 来做到这一点。使用柴油对我来说不是一个选择。
这是我在数据库方面想到的:
CREATE TABLE workplaces (
id BIGSERIAL PRIMARY KEY,
place TEXT NOT NULL
);
CREATE TABLE workers (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE workplaces_workers (
workplace_id BIGINT NOT NULL REFERENCES workplaces (id) ON DELETE CASCADE,
workers_id BIGINT NOT NULL REFERENCES workers (id) ON DELETE CASCADE,
PRIMARY KEY (workplace_id, workers_id)
);
Run Code Online (Sandbox Code Playgroud)
到目前为止,这是我的 Rust 代码:
pub struct Workplace {
pub id: i64,
pub …Run Code Online (Sandbox Code Playgroud) 代码:
// 非常复杂的 where 子句由多个运行时变量组合而成。
let query: String = String.from("where ..........");
let rows_num: i64 = sqlx::query!( &*query).fetch_one(connection)
Run Code Online (Sandbox Code Playgroud)
编译器的错误:
error: expected string literal
--> src/abc.rs:80:25
|
80 | let rows_num: i64 = sqlx::query!(
| ____________^
81 | | &*query,
82 | | ).fetch_one(connection)
| |^
|
= note: this error originates in the macro sqlx::query (in Nightly builds, run with -Z macro-backtrace for more info)
Run Code Online (Sandbox Code Playgroud)
该文档指出:
查询必须是字符串文字,否则无法内省(因此不能是动态的或另一个宏的结果)。
我知道 sqlx 在编译时计算,我的 where 子句计算在运行时。我真的很想使用变量,因为 where 子句取决于其他几个条件。有什么方法可以在sqlx中使用变量吗?
我正在尝试在 Postgres 中创建自定义枚举类型并已成功完成。我的迁移看起来像这样:
CREATE TYPE role AS ENUM ('admin', 'user');
ALTER TABLE users
ADD role role DEFAULT 'user';
Run Code Online (Sandbox Code Playgroud)
然后我在 Rust 中创建了枚举类型,如下所示:
#[derive(Serialize, Deserialize, Debug, sqlx::Type)]
#[sqlx(type_name = "role", rename_all = "lowercase")]
pub enum Role {
ADMIN,
USER
}
Run Code Online (Sandbox Code Playgroud)
我也改变了用户模型:
#[derive(sqlx::FromRow, Debug)]
pub struct User {
pub id: i32,
pub email: String,
pub username: String,
pub password: String,
pub role: Role,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
Run Code Online (Sandbox Code Playgroud)
但现在当我尝试像这样查询数据库时:
let user = match sqlx::query_as!(
User,
"SELECT * FROM users WHERE email …Run Code Online (Sandbox Code Playgroud) 我正在使用一些 sqlx::query!和 sqlx::query_as! 我的项目编译得很好。但是当我运行 Cargo sqlxprepare 时,我首先得到错误:
$ cargo sqlx prepare
error: extra arguments to `rustc` can only be passed to one target, consider filtering
the package by passing, e.g., `--lib` or `--bin NAME` to specify a single target
error: `cargo check` failed with status: exit status: 101
Run Code Online (Sandbox Code Playgroud)
然后当我用“--lib”运行它时,我得到:
$ cargo sqlx prepare -- --lib
Compiling crate v0.1.0 (/Users/ryan/Documents/crate)
Finished dev [unoptimized + debuginfo] target(s) in 5.78s
warning: no queries found; please ensure that the `offline` feature is enabled in …Run Code Online (Sandbox Code Playgroud)