データベース接続パラメータが一般的なデータベースにタイプを挿入し、複数のバックエンドで動作できるようにする関数を記述します。ディーゼルの形質バウンドエラーの理解
私は、一般的な接続を使用してオブジェクトを挿入するには、以下の機能を思い付いた:
pub fn create_label<C>(connection: &C, label: &model::Label)
where
C: Connection,
C::Backend: diesel::backend::Backend,
C::Backend: diesel::backend::SupportsDefaultKeyword,
{
diesel::insert(&label)
.into(schema::label::table)
.execute(connection);
}
私はSupportsDefaultKeyword
制約が含まれていない場合は、関数がコンパイルされません。接続パラメータとしてSqliteConnection
でそれを呼び出すとき、私は次のエラーを取得する:
database::create_label(&db_conn, &label); ^^^^^^^^^^^^^^^^^^^^^^ the trait 'diesel::backend::SupportsDefaultKeyword' is not implemented for 'diesel::sqlite::Sqlite'
これはSqliteConnection
にデータを挿入すると、動作しないことを意味します。それは明らかにそうではありません。さらに、create_label
を変更すると、SqliteConnection
という名前がそのまま正しく動作します。
pub fn create_label(connection: &SqliteConnection, label: &model::Label) {
diesel::insert(&label)
.into(schema::label::table)
.execute(connection);
}
なぜそれが一般的な機能はSupportsDefaultKeyword
制約を必要としSqliteConnection
を取る機能がないということでしょうか?
ここには、問題を示すminimal exampleがあります。ライン61は、コンパイルないのに対し、コメント通り、ラインmain.rs
60は、上記のエラーでコンパイルされません:execute
が複数の具体的な実装を有する
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_codegen;
mod schema {
table! {
labels {
id -> Integer,
name -> VarChar,
}
}
}
mod model {
use schema::labels;
#[derive(Debug, Identifiable, Insertable)]
#[table_name = "labels"]
pub struct Label {
pub id: i32,
pub name: String,
}
}
use diesel::ExecuteDsl;
use diesel::Connection;
use diesel::prelude::*;
use diesel::sqlite::SqliteConnection;
pub fn create_label<C>(connection: &C, label: &model::Label)
where
C: Connection,
C::Backend: diesel::backend::Backend,
C::Backend: diesel::backend::SupportsDefaultKeyword,
{
diesel::insert(label)
.into(schema::labels::table)
.execute(connection)
.expect("nope");
}
pub fn create_label_sqlite(connection: &SqliteConnection, label: &model::Label) {
diesel::insert(label)
.into(schema::labels::table)
.execute(connection)
.expect("nope");
}
pub fn establish_connection() -> SqliteConnection {
let url = "test.db";
SqliteConnection::establish(&url).expect(&format!("Error connecting to {}", url))
}
fn main() {
let label = model::Label {
id: 1,
name: String::from("test"),
};
let conn = establish_connection();
create_label(&conn, &label); /* Does not compile */
create_label_sqlite(&conn, &label); /*Compiles */
}
[dependencies]
diesel = { version = "0.16.0", features = ["sqlite"] }
diesel_codegen = "0.16.0"