为什么 Rusqlite 在执行查询时拒绝 Option 类型? [英] Why does Rusqlite reject the Option type when executing a query?
问题描述
我正在尝试将 CSV 数据插入到 SQLite 数据库中.stripe_id
是可选的,所以它的类型是 Option<&str>
.所有其他字段都是 &str
.当我使用 conn.execute
插入值时,除了 stripe_id
之外,它们都正确插入,这会抛出一个错误,说它需要 &str
而不是 Option
.
I'm trying to insert CSV data into a SQLite database. stripe_id
is optional, and so its type is Option<&str>
. All the other fields are &str
. When I use conn.execute
to insert the values, they all insert correctly except for stripe_id
, which throws an error saying it expects &str
and not Option
.
我搜索了文档并且 Option
实现了 ToSQL
,当我尝试用包含 的 Rusqlite 示例替换我的代码时Option
值,它会为示例代码抛出相同的错误.
I've searched the docs and Option<T>
implements ToSQL
, and when I've tried replacing my code with the Rusqlite example that includes an Option
value, it throws the same error for the example code.
相关的结构和查询代码片段:
The relevant struct and query code snippet:
struct Merchant<'a> {
name: &'a str,
billing_portal: &'a str,
billing_period: &'a str,
stripe_id: Option<&'a str>,
}
conn.execute(
"INSERT INTO merchants (name, billing_portal, billing_period, stripe_id)
values (?, ?, ?, ?)",
&[&merch.name, &merch.billing_portal, &merch.billing_period, &merch.stripe_id]
).expect("Error inserting merchant into database");
错误:
error[E0308]: mismatched types
--> src/main.rs:38:75
|
38 | &[&merch.name, &merch.billing_portal, &merch.billing_period, &merch.stripe_id]
| ^^^^^^^^^^^^^^^^ expected `&str`, found enum `std::option::Option`
|
= note: expected reference `&&str`
found reference `&std::option::Option<&str>`
以及完整的代码:
extern crate csv;
extern crate rusqlite;
use rusqlite::{Connection, Result};
#[derive(Debug)]
struct Merchant<'a> {
name: &'a str,
billing_portal: &'a str,
billing_period: &'a str,
stripe_id: Option<&'a str>,
}
fn main() -> Result<()> {
let conn = Connection::open("data.sqlite")?;
let mut reader = csv::ReaderBuilder::new()
.has_headers(false)
.from_path("merchants.csv")
.expect("Failed to read csv");
for record in reader.records() {
let record = record.unwrap();
let merch = Merchant {
name: &record[0],
billing_portal: &record[3],
billing_period: &record[4],
stripe_id: (match &record[5] {
x if x == "" => None,
x => Some(x)
}),
};
println!("{:?}", &merch);
conn.execute(
"INSERT INTO merchants (name, billing_portal, billing_period, stripe_id)
values (?, ?, ?, ?)",
&[&merch.name, &merch.billing_portal, &merch.billing_period, &merch.stripe_id]
).expect("Error inserting merchant into database");
}
Ok(())
}
推荐答案
使用 rusqlite::params
宏解决问题:
Using the rusqlite::params
macro solves the problem:
use rusqlite::{params, Connection, Result};
fn main() -> Result<()> {
// ...
for record in reader.records() {
// ...
conn.execute(
"INSERT INTO merchants (name, billing_portal, billing_period, stripe_id)
values (?, ?, ?, ?)",
params![
&merch.name,
&merch.billing_portal,
&merch.billing_period,
&merch.stripe_id,
],
)
.expect("Error inserting merchant into database");
}
Ok(())
}
这篇关于为什么 Rusqlite 在执行查询时拒绝 Option 类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!