sqlite - 为什么 Rusqlite 在执行查询时会拒绝 Option 类型?
问题描述
我正在尝试将 CSV 数据插入 SQLite 数据库。stripe_id
是可选的,所以它的类型是Option<&str>
. 所有其他字段都是&str
. 当我conn.execute
用来插入值时,它们都正确插入,除了stripe_id
,它会抛出一个错误,说它期望&str
而不是Option
。
我搜索了文档和Option<T>
实现ToSQL
,当我尝试用包含Option
值的 Rusqlite 示例替换我的代码时,它会为示例代码引发相同的错误。
相关结构和查询代码片段:
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
宏解决了这个问题:
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(())
}
推荐阅读
- ruby-on-rails - 设计运行不正常
- android - Android 片段:重叠 - 替换后仍然可见
- java - Java 虚拟受限存储(虚拟磁盘、映像、加密的 zip 文件等...)
- java - 如何在 Spring 中更改 Application.properties 的值
- gitlab - GitLab管道中`environment:url`使用的`CI_COMMIT_TAG`的字符串操作
- kubernetes - 在启动新 Pod 之前强制关闭 Kubernetes Pod,以防中断
- php - 使用对象作为键的多维地图
- python - TypeError:不支持的操作数类型 -=:python 上的 'slice' 和 'int'
- ios - 如何在ios swift中将新值添加到数组时实时更新tableview
- node.js - 使用快速身份验证对用户隐藏特定选项卡