Diesel 所需 Rust 版本 >= 1.65
安装至项目
修改 Cargo.toml
[dependencies]
diesel = { version = "2.1.0", features = ["postgres"] }
dotenvy = "0.15"
安装 CLI
Diesel 提供了用于管理项目的命令行工具,可以通过 cargo 安装。
cargo install diesel_cli
但是,你可能会遇到这样的问题:
note: ld: library not found for -lmysqlclient
clang: error: linker command failed with exit code 1 (use -v to see invocation)
这是系统缺乏相关的用于操作数据库的链接库导致的,这里阐述使用 Sqlite 的时候的解决方法。
在报错的终端搜索
LIBPATH
,复制其值;打开
LIBPATH
所在的目录,我们需要把链接库放在这里;对于 Sqlite,我们可以在 Cargo.toml 的
[dependencies]
块中加入:rusqlite = { version = "0.31.0", features = ["bundled"] }
编译项目,然后在编译目录下的
build
文件夹找到libsqlite3-sys-*
文件夹,*
表示一串哈希字符串。可能会包含多个这样的文件夹。找到其中包含的out/libsqlite3.a
文件,把libsqlite3.a
复制到前面打开的LIBPATH
中。再次安装CLI,由于我们只添加了 sqlite 库,所以我们需要指定
features
cargo install diesel_cli --no-default-features --features sqlite
对于其它数据库,
features
需要如下填写数据库 features MySQL mysql PostgreSQL postgres SQLite sqlite diesel/.github/workflows/ci.yml at master · diesel-rs/diesel
项目初步设置
首先,我们需要在项目根目录下创建一个 .env
文件,在其中写入数据库的地址:
DATABASE_URL=postgres://username:password@localhost/diesel_demo
对于SQLite 数据库,示例如下:
DATABASE_URL=sqlite://database.db
Windows 下不建议使用 echo 指令,因为操作系统可能不会以 UTF8 格式写入文件,导致文件无法读取
然后,我们就可以使用 CLI 让 Diesel 帮我们初始化项目,包括:
- 创建数据库
- 创建数据库迁移文件夹(用于生成数据库结构)
创建第一个表
对于表的创建,Diesel 需要同时拥有过该表的迁移和 Schema,但 Diesel 可以根据其一生成另一。
- 手动定义 迁移,Diesel 在迁移时自动生成 Schema
- 手动定义 Schema,Diesel 在迁移时自动生成 迁移
创建第一个表(SQL)
我们可以使用 Diesel 的数据库迁移功能来创建数据库结构,并对数据库的结构进行版本控制。首先,我们需要生成迁移文件:
diesel migration generate create_posts
其中 create_posts
即为迁移的名称,最终会以 时间_crewate_posts
方式生成文件夹,并生成 up.sql
和 down.sql
分别用于构建和撤销数据库结构。
举例来说,我们可以在 up.sql
中写入:
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
title VARCHAR NOT NULL,
body TEXT NOT NULL,
published BOOLEAN NOT NULL DEFAULT FALSE
)
在 down.sql
中删除改表:
DROP TABLE posts
创建迁移后,我们可以开始迁移(根据 up.sql
)
diesel migration run
也可以撤销已经进行的迁移(根据 down.sql
)
diesel migration redo
创建第一个表 (schema)
使用 SQL 创建迁移可以最大程度地保留灵活性,但是 Diesel 也支持使用 schema 来进行迁移,我们将在 schema 文件中定义表及其对应的 Rust 类型,Diesel 会自动推断其在数据库中的类型。
创建 schema.rs
文件,并写入表结构,如:
diesel::table! {
posts (id) {
id -> Int4,
title -> Varchar,
body -> Text,
published -> Bool,
}
}
然后,我们还需要生成迁移文件:
diesel migration generate --diff-schema create_posts
有了迁移文件后,一切就如前文所述的一样运行迁移即可。
生产环境下运行迁移
我们不能要求用户安装 Diesel CLI 并运行迁移指令,Diesel 提供了在代码中运行迁移的方法,这个方法是:
- 使用在
diesel_migrations
crate 中的embed_migrations!
宏,这样迁移文件会包含在最终的二进制文件中; - 使用
connection.run_pending_migrations(MIGRATIONS)
代码进行迁移。
示例:
diesel_migrations = { version = "2.1.0", features = ["sqlite"]}
use diesel::sqlite::SqliteConnection;
use diesel::prelude::*;
use dotenvy::dotenv;
use std::env;
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
pub fn establish_connection() -> SqliteConnection {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
SqliteConnection::establish(&database_url)
.unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
}
fn main() {
let conn = &mut establish_connection();
const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
let _ = conn.run_pending_migrations(MIGRATIONS);
// ...
}
注意,若不引入 diesel_migrations::MigrationHarness
trait,则无法使用 run_pending_migrations
方法。