如何使用Diesel和SQLite获取新创建值的ID?

aor9mmx1  于 2023-10-23  发布在  SQLite
关注(0)|答案(2)|浏览(238)

Diesel的SqliteBackend没有实现SupportsReturningClause trait,因此get_result方法不能用于检索新创建的值。
是否有其他方法可以找到插入行的id?Python has a solution for this。到目前为止,我找到的唯一解决方案是使用UUID作为id,而不是使用自动递增字段。

dvtswwa3

dvtswwa31#

这里的潜在问题是SQLite不支持SQL RETURNING子句,这将允许您返回自动生成的id作为插入语句的一部分。
由于OP只提供了一个一般性的问题,我不能展示如何使用柴油实现的例子。
有几种方法可以解决这个问题。所有这些都要求您执行第二个查询。
1.按id排序,只选择最大的id。这是最直接的解决办法。它直接显示了进行第二次查询的问题,因为在任何时候都可能有一个竞争插入,这样你就可以得到错误的id(至少如果你不使用transactions)。
1.使用last_insert_rowid() SQL函数接收最后插入的列的行ID。如果未配置,则这些行id与自动递增主整数键匹配。在diesel端,你可以使用no_arg_sql_function!()在你的crate中定义底层的sql函数。

js5cn81o

js5cn81o2#

正如自SQLite 3.35 / Diesel 2.0以来的comments中所指出的那样,您也可以通过使用returning_clauses_for_sqlite_3_35功能将.get_result()与SQLite后端一起使用。
假设我们有一个名为tournaments的表

CREATE TABLE tournaments (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    name VARCHAR NOT NULL
)

如果我们想在其中添加一个新的锦标赛,我们可以得到插入的行.get_result()

// Schema
// @generated automatically by Diesel CLI.
diesel::table! {
    tournaments (id) {
        id -> Integer,
        name -> Text,
    }
}

// Model
#[derive(Insertable)]
#[diesel(table_name = tournaments)]
pub struct NewTournament<'a> {
    pub name: &'a str
}

fn new_tournament(name: &str, connection: diesel::sqlite::SqliteConnection) -> i32 {
    println!("Adding new tournament \"{name}\"");
    let new_tournament = NewTournament {name: name};
    let result = diesel::insert_into(tournaments::table)
        .values(new_tournament)
        .get_result::<(i32, String)>(&mut connection).unwrap();
    result.0

相关问题