Diesel SQLite 入门第一步迁移、schema 自动生成与首个查询程序【免费下载链接】dieselA safe, extensible ORM and Query Builder for Rust项目地址: https://gitcode.com/gh_mirrors/di/diesel本文基于 Diesel 官方Getting Started指南的 SQLite 移植示例examples/sqlite/getting_started_step_1手把手带你走完一条最小可运行的完整链路配置数据库连接、编写并执行迁移、自动生成 schema、定义模型最后用cargo run跑出第一个查询二进制。读完本篇你将掌握在 Rust 项目里用 Diesel CLI SQLite 搭建「迁移 → schema → 模型 → 查询」全流程的基础能力并能在本仓库中对照源码与测试用例验证每一步的实际行为。示例概览这个示例要解决什么问题examples/sqlite/getting_started_step_1是 Diesel 官方 Getting Started 系列的第一步它把官方入门教程中默认的 PostgreSQL 后端替换成了SQLite。示例的完整目标非常聚焦建立一个能查询posts表的命令行程序show_posts_step_1它会从数据库读取所有已发布的文章并打印出来。该示例的运行前提非常简单——只需要一个本地 SQLite 文件不需要安装任何数据库服务。整个示例的核心文件如下examples/sqlite/getting_started_step_1/ ├── Cargo.toml # 依赖与二进制声明 ├── diesel.toml # Diesel CLI 配置print_schema 输出位置 ├── README.md # 使用说明 ├── migrations/ │ └── 20170124012402_create_posts/ │ ├── up.sql # 建表迁移 │ └── down.sql # 回滚迁移 ├── src/ │ ├── bin/show_posts.rs # 可执行查询程序 │ ├── lib.rs # 连接建立函数 │ ├── models.rs # Post 模型定义 │ └── schema.rs # 由 CLI 自动生成的 schema └── tests/step_1.rs # 端到端集成测试第一步写入数据库连接配置示例 README 的 Usage 部分给出的第一步是创建.env文件并写入数据库连接串$ echo DATABASE_URLfile:test.db .envSQLite 的连接串使用file:前缀加文件路径的形式这里test.db就是相对于项目根目录的数据库文件。dotenvy依赖负责在运行时加载.env详见 Cargo.toml 中的dotenvy 0.15而 Diesel CLI 在读取配置时同样会加载.env因此这个文件同时服务于 CLI 与运行时程序。需要特别指出的是示例代码在读取环境变量时提供了两级回退src/lib.rs 中优先读取SQLITE_DATABASE_URL若未设置则回退到DATABASE_URL。这一点在测试场景中非常关键——集成测试正是通过覆盖SQLITE_DATABASE_URL来指向临时数据库见下文「测试验证」一节。第二步声明依赖并理解 Cargo.toml 的构成examples/sqlite/getting_started_step_1/Cargo.toml 是本示例的依赖声明核心[dependencies] diesel { version 2.3.0, path ../../../diesel, features [sqlite] } libsqlite3-sys { workspace true, features [bundled] } dotenvy 0.15 [dev-dependencies] assert_cmd 2.1 tempfile 3 diesel_migrations { version 2.3.0, path ../../../diesel_migrations } [[bin]] name show_posts_step_1 path src/bin/show_posts.rs doc false几个值得注意的配置点features [sqlite]Diesel 通过 feature 开关选择后端这里启用了 SQLite 支持对应仓库中 diesel/src/sqlite 这一整套后端实现libsqlite3-sys的bundled特性把 SQLite 的 C 源码直接编译进程序使用者无需在系统里预先安装 SQLite 开发库这也是本示例可以零环境依赖直接运行的原因[[bin]]段显式声明名为show_posts_step_1的二进制其入口位于src/bin/show_posts.rs。注意README 中给出的运行命令是cargo run --bin show_posts而实际二进制名是show_posts_step_1Cargo.toml 中以name show_posts_step_1声明运行时请以 Cargo.toml 中的声明为准。第三步编写并执行迁移示例自带一个建表迁移20170124012402_create_posts其中up.sql负责正向建表-- examples/sqlite/getting_started_step_1/migrations/20170124012402_create_posts/up.sql CREATE TABLE posts ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, title VARCHAR NOT NULL, body TEXT NOT NULL, published BOOLEAN NOT NULL DEFAULT 0 )对应的down.sql负责回滚DROP TABLE posts执行迁移的命令即 README 中的第二步$ diesel migration runDiesel CLI 会扫描migrations/目录目录名前缀是时间戳用于保证迁移顺序执行所有尚未应用的up.sql并把执行记录写入数据库内部的__diesel_schema_migrations表从而保证迁移只执行一次。迁移执行成功后CLI 会根据 diesel.toml 中的print_schema配置自动生成src/schema.rs# diesel.toml [print_schema] file src/schema.rs生成结果与仓库中 src/schema.rs 完全一致// generated automatically by Diesel CLI. diesel::table! { posts (id) { id - Integer, title - Text, body - Text, published - Bool, } }这段table!宏生成的posts::table与posts::dsl模块是后续所有类型安全查询的基石——它把 SQL 列名映射为 Rust 类型INTEGER → Integer、TEXT → Text、BOOLEAN → Bool任何类型不匹配的查询都会在编译期被拒绝这正是 Diesel 所谓「类型安全 SQL」的直接体现。从源码结构看table!宏由 diesel/src/internal/table_macro.rs 与 diesel_derives/src/table.rs 联合展开实现。第四步定义与表结构对应的模型有了 schema 之后还需要一个与之对应的 Rust 结构体来描述查询结果。src/models.rs 中定义了Postuse diesel::prelude::*; #[derive(Queryable, Selectable)] #[diesel(table_name crate::schema::posts)] #[diesel(check_for_backend(diesel::sqlite::Sqlite))] pub struct Post { pub id: i32, pub title: String, pub body: String, pub published: bool, }这里涉及两个关键派生宏Queryable让Post能从查询结果的原始行反序列化出来对应 diesel_derives/src/queryable.rs 的实现Selectable让Post可以配合as_select()使用将结构体字段映射为 SELECT 列对应 diesel_derives/src/selectable.rs。check_for_backend属性则把模型与 SQLite 后端绑定确保该模型不会误用于其他数据库。第五步建立数据库连接src/lib.rs 提供了全示例共用的连接函数pub fn establish_connection() - SqliteConnection { dotenv().ok(); let database_url env::var(SQLITE_DATABASE_URL) .or_else(|_| env::var(DATABASE_URL)) .expect(DATABASE_URL must be set); SqliteConnection::establish(database_url) .unwrap_or_else(|e| panic!(Failed to connect, error: {e})) }调用链很清晰dotenv()加载.env→ 读取连接串优先SQLITE_DATABASE_URL回退DATABASE_URL→SqliteConnection::establish建立连接。SqliteConnection位于 diesel/src/sqlite/connection 模块establish会打开指定的 SQLite 文件不存在时会自动创建。第六步编写并运行第一个查询程序核心业务逻辑集中在 src/bin/show_posts.rsuse self::models::*; use diesel::prelude::*; use getting_started_step_1_sqlite::*; fn main() { use self::schema::posts::dsl::*; let connection mut establish_connection(); let results posts .filter(published.eq(true)) .limit(5) .select(Post::as_select()) .load(connection) .expect(Error loading posts); println!(Displaying {} posts, results.len()); for post in results { println!({}, post.title); println!(----------\n); println!({}, post.body); } }这段代码把 Diesel 的类型安全查询链体现得淋漓尽致posts.filter(published.eq(true))只取已发布的文章eq等操作符由 diesel/src/expression_methods/global_expression_methods.rs 提供.limit(5)限制最多 5 条结果.select(Post::as_select())借助Selectable派生将结构体字段展开为 SELECT 列.load(connection)执行查询并把结果加载为VecPost。按 README 执行第三步即可运行$ cargo run --bin show_posts_step_1在空数据库上运行会输出Displaying 0 posts一旦posts表中有已发布的数据就会逐条打印标题与正文。测试验证集成测试如何覆盖完整流程examples/sqlite/getting_started_step_1/tests/step_1.rs 给出了一个不依赖外部环境的端到端测试完整复刻了「建库 → 跑迁移 → 运行二进制 → 校验输出」的流程#[test] fn show_posts() { let temp_dir tempfile::tempdir().unwrap(); let db_url temp_dir.path().join(test.db).display().to_string(); let mut conn SqliteConnection::establish(db_url).unwrap(); let migrations diesel_migrations::FileBasedMigrations::find_migrations_directory().unwrap(); conn.run_pending_migrations(migrations).unwrap(); let _ cargo_bin_cmd!(show_posts_step_1) .env(SQLITE_DATABASE_URL, db_url) .assert() .append_context(show_posts, ) .stdout(Displaying 0 posts\n); }这个测试揭示了三个关键点FileBasedMigrations::find_migrations_directory()会从项目根目录自动发现migrations/目录并通过run_pending_migrations以编程方式应用迁移——这正是命令行diesel migration run在测试中的等价物其能力来自 diesel_migrations crateSQLITE_DATABASE_URL环境变量的优先级在此得到验证测试通过.env(SQLITE_DATABASE_URL, db_url)把连接指向临时目录中的test.db从而完全隔离测试环境tempfile::tempdir()保证测试结束后临时数据库自动清理运行cargo test即可无残留地反复执行。总结与后续学习路径通过getting_started_step_1你已完成 Diesel SQLite 从零到可查询的完整闭环用.env配置DATABASE_URLfile:test.db声明带sqlitefeature 的 diesel 依赖含bundledSQLite零外部依赖编写up.sql/down.sql迁移并执行diesel migration run由 CLI 自动生成src/schema.rs获得编译期类型安全用QueryableSelectable派生定义模型编写establish_connection与查询二进制并运行验证。下一步可以继续研读同系列示例examples/sqlite/getting_started_step_2增加插入与更新操作和getting_started_step_3引入关联与批量查询进一步体验 Diesel 在更复杂数据操作上的能力。【免费下载链接】dieselA safe, extensible ORM and Query Builder for Rust项目地址: https://gitcode.com/gh_mirrors/di/diesel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
面试突击:咖啡法则避坑指南,3个核心考点吃透 面试突击:咖啡法则避坑指南,3个核心考点吃透 看到“咖啡法则”这四个字,很多后端开发者第一反应是懵的:这是哪个大厂自创的黑话?还是某个新出的开源库?别慌,在技术面试的语境里,这往往指的是**“Code is Poetry”(代码即诗歌)… · 2026/9/22 11:16:24
数据有效性在哪里新手避坑指南:3个工具对比 数据有效性在哪里新手避坑指南:3个工具对比 报错一堆看不懂 StackTrace?别慌,这通常是数据有效性没搞对。 很多新手在调试时,看到满屏红色异常信息直接懵圈,其实根源往往在于输入数据不符合预期格式。… · 2026/9/22 11:16:24
SUPERVOOC S快充芯片深度解析:集成化设计、协议握手与维修实战 1. 从一颗"消失"的充电芯片说起如果你拆过最近两年的OPPO中高端机型,会发现一个挺有意思的现象:主板上的充电管理区域,原本密密麻麻的电源芯片和外围阻容,突然变得干净了不少。以前快充电路里常见的几颗独立芯片——协议… · 2026/9/22 12:22:24
oppo全面屏适配踩坑实录:3个高频面试题背后的源码真相 oppo全面屏适配踩坑实录:3个高频面试题背后的源码真相 刚接手一个老项目,编译报错堆满屏幕。Stack Trace 像天书一样滚动,第一行就是 android.view.WindowManager$BadTokenException… · 2026/9/22 12:22:18
问道注册面试必问:3个性能优化点让你的注册服务快10倍 问道注册面试必问:3个性能优化点让你的注册服务快10倍 别再说自己只会写 CRUD 了。很多开发者刚入门时,对着语法手册能背下所有关键字,但真到了搭建一个像“问道注册”这样的真实业务模块,脑子瞬间一片空白。这种“懂语法但不会搭项目”的断层,… · 2026/9/22 12:22:18
正态分布图怎么做不报错?3个常见坑的保姆级教程 正态分布图怎么做不报错?3个常见坑的保姆级教程 刚学会 matplotlib 的基本语法,想画个正态分布图展示数据分布,结果跑起来全是坑?别慌,这不是你的问题。很多开发者都卡在这一步:代码能跑通,但图不对、轴乱了、或者干脆报错。 这篇… · 2026/9/22 12:21:54
川农教务网代码跑不通?3个高频面试题级Bug排查实战 川农教务网代码跑不通?3个高频面试题级Bug排查实战 刚把同事给的 sichuan-agri-login.py 丢进 PyCharm,回车一敲,屏幕直接弹红字 SSLError: certificate verify failed… · 2026/9/22 12:21:29
青春搏击主题曲渲染卡顿?这份避坑指南救了我的命 青春搏击主题曲渲染卡顿?这份避坑指南救了我的命 复制来的代码跑不通,报错信息满屏飞,鼠标转圈转到怀疑人生?别急,这不是你的问题,是代码没调教好。今天我们就拿那个让人头大的“青春搏击主题曲”动态视觉化项目开刀,聊聊从卡成PPT到丝滑60帧的… · 2026/9/22 12:21:23
5个电影海报图片处理坑,新手避坑指南 5个电影海报图片处理坑,新手避坑指南 刚写完代码,一运行屏幕直接炸了。满屏红色的 StackTrace 滚得比弹幕还快,什么 NullPointerException 、 ImageIO.read() returned null 、… · 2026/9/22 0:00:07
注册微信公众账号:一文搞懂从0到1全流程 注册微信公众账号:一文搞懂从0到1全流程 复制来的代码跑不通,报错信息满屏飞,到底卡在哪?别急,咱们先停下手里的调试。很多开发者觉得注册微信公众账号只是填个表单、传个身份证那么简单,真上手才发现坑深不见底。今天这篇 一文搞懂… · 2026/9/22 0:00:07