You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust sqlx执行INSERT无数据变更 重复插入报已存在错误

问题原因

核心问题是Postgres连接配置漏传了目标数据库名称。
构建PgConnectOptions时你只配置了主机、端口、用户名、密码、SSL模式,没有调用.database()方法指定要连接的业务库,此时sqlx会默认连接与用户名同名的数据库(多数场景下是默认的postgres系统库,或是和数据库账号同名的空库):

  • 执行INSERT时实际写入的是这个默认库,不是预期的业务库,所以查询业务库看不到任何数据变更
  • 反复往这个默认库的同一张表插入带相同唯一键的数据,自然会触发唯一约束冲突,返回记录已存在的错误
修复步骤
  • 补全连接配置的数据库名参数,修改连接初始化代码如下:
let from_ssl = |ssl: bool| -> PgSslMode {
    match ssl {
        true => PgSslMode::Require,
        false => PgSslMode::Disable,
    }
};
let conn = PgConnectOptions::new()
    .host(db.host.as_str())
    .port(db.port)
    .username(db.user.as_str())
    .password(db.password.as_str())
    .database(db.dbname.as_str()) // 新增该行,传入你要操作的业务库名称
    .ssl_mode(from_ssl(db.ssl));

let pool = PgPoolOptions::new()
    .max_connections(5)
    .idle_timeout(Some(Duration::new(60, 0)))
    .connect_with(conn)
    .await?;

Ok(DbBuilder { pool })
  • (低概率排查项)如果补全库名后仍有异常,检查代码中是否存在未显式提交的事务:sqlx的事务实例如果没有调用.commit().await就离开作用域,会自动触发回滚,也会导致数据不落地。你贴出的INSERT代码是直接通过连接池执行,单条语句默认自动提交,一般不会触发这个问题。
  • 验证修复结果:插入后在同连接池执行对应条件的SELECT查询,同时确认你的数据库客户端连接的是同一个业务库,避免客户端缓存、连错实例导致的看不到数据的误判。

你贴出的INSERT语句本身没有语法问题,不需要修改:

sqlx::query!("INSERT INTO configs \
            (name, is_available, membership_id, priority_index, params)\
            VALUES( $1, $2 ,$3 ,$4, $5);",
               name, is_available, 1, 1, params)
                .execute(&db.pool)
                .await?;

内容的提问来源于stack exchange,提问作者Gleb Protasov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 21:15:41