域名 AXUM.RS 将于2025年10月到期。我们无意再对其进行续费,我们希望你能够接续这个域名,让更多 AXUM 开发者继续受益。现在,我们已启用新域名 AXUM.EU.ORG
  • 方案AXUM.RS 域名 = 3000
如果你有意接续这份 AXUM 情怀,请与我们取得联系。
说明:
  1. 如果有人购买 AXUM.RS 域名,或者该域名到期,本站将使用免费域名 AXUM.EU.ORG 继续提供服务。

使用 sqlx 操作 PostgreSQL 数组

PostgreSQL 原生支持数组。本章将讨论如何使用 sqlx 操作 PostgreSQL 的数组。

我们使用一个极简的“朋友圈”动态来做示例。

数据表定义

CREATE TABLE IF NOT EXISTS "posts"(
    "id" SERIAL PRIMARY KEY,
    "content" VARCHAR(255) NOT NULL,
    "images" VARCHAR(50)[] NOT NULL DEFAULT '{}'::VARCHAR(50)[]
);
  • content:内容
  • images:图片,数据类型为varchar(50)的数组。默认值为空数组

模型定义

// src/post/model.rs

#[derive(Default, Serialize, Deserialize, FromRow)]
pub struct Post {
    pub id: i32,
    pub content: String,
    pub images: Vec<String>,
}
pub async fn create(e: impl PgExecutor<'_>, m: &Post) -> sqlx::Result<i32> {
    let (id,): (i32,) =
        sqlx::query_as(r#"INSERT INTO posts ("content", images) VALUES ($1, $2) RETURNING id"#)
            .bind(&m.content)
            .bind(&m.images)
            .fetch_one(e)
            .await?;
    Ok(id)
}

pub async fn find(e: impl PgExecutor<'_>, id: i32) -> sqlx::Result<Option<Post>> {
    sqlx::query_as(r#"SELECT id, "content", images FROM posts WHERE id = $1"#)
        .bind(id)
        .fetch_optional(e)
        .await
}

handler

// src/post/handler.rs

#[derive(Deserialize)]
pub struct CreateForm {
    content: String,
    images: Vec<String>,
}
pub async fn create(
    State(state): State<ArcAppState>,
    Json(frm): Json<CreateForm>,
) -> Result<Json<i32>> {
    let id = model::create(
        &state.pool,
        &model::Post {
            content: frm.content,
            images: frm.images,
            ..Default::default()
        },
    )
    .await?;

    Ok(Json(id))
}

pub async fn find(
    State(state): State<ArcAppState>,
    Path(id): Path<i32>,
) -> Result<Json<model::Post>> {
    let post = match model::find(&state.pool, id).await? {
        Some(v) => v,
        None => return Err(Error::new("不存在的记录")),
    };

    Ok(Json(post))
}

测试

要查看完整内容,请先登录