数据库后端【免费下载链接】sqlx The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, and SQLite.项目地址https://gitcode.com/gh_mirrors/sql/sqlx点击查看免费下载SQLx 是 Rust 生态中主打“异步、纯 Rust、无需 DSL 即可实现编译期查询检查”的 SQL 工具包内置对 PostgreSQL、MySQL 与 SQLite 的支持。本文以仓库中 examples/sqlite/todos 示例为主线完整讲解从设置DATABASE_URL、用sqlx-cli创建数据库与执行迁移到用query!宏编写增、改、查三种操作的完整流程。读完本文你将掌握 SQLx SQLite 的最小可运行工程模板理解连接池与编译期检查查询宏的用法并能独立复现这套“先迁移、后编码”的开发节奏。示例定位一个最小的 SQLx SQLite 命令行应用examples/sqlite/todos是一个自包含的 TODO 命令行程序通过clap解析子命令通过sqlx连接 SQLite 数据库文件并通过query!宏在编译期校验 SQL 的正确性。它同时示范了 SQLx 项目中最常见的两个组成部分迁移Migrations用sqlx-cli管理数据库结构变更迁移脚本存放在 examples/sqlite/todos/migrations/20200718111257_todos.sql运行时数据访问在 examples/sqlite/todos/src/main.rs 中完成新增、完成、列举三类操作。示例依赖配置见 examples/sqlite/todos/Cargo.toml其核心依赖为sqlx { path ../../../, features [ sqlite, runtime-tokio, tls-native-tls ] } clap { version 4.4.7, features [derive] } tokio { version 1.25.0, features [rt, macros] }注意sqlx需要显式开启sqlite特性与某个运行时此处为runtime-tokio并搭配anyhow简化错误处理tokio只需rt与macros两个特性因为该示例使用单线程运行时的#[tokio::main(flavor current_thread)]入口无需多线程 IO。一、环境准备声明数据库 URL示例的第一步是声明数据库连接串。对于 SQLite数据库“URL”实际上就是一个文件路径export DATABASE_URLsqlite:todos.db这里sqlite:是 SQLx 识别 SQLite 驱动的前缀后面直接跟数据库文件名todos.db。从 sqlx-sqlite/src/options/parse.rs 的解析逻辑可以看到SqliteConnectOptions的FromStr实现会依次剥离sqlite://与sqlite:前缀再按?切分数据库名与查询参数// sqlx-sqlite/src/options/parse.rs fn from_str(mut url: str) - ResultSelf, Self::Err { // remove scheme from the URL url url .trim_start_matches(sqlite://) .trim_start_matches(sqlite:); let mut database_and_params url.splitn(2, ?); ... }因此sqlite:todos.db、sqlite://todos.db都是合法的写法。除文件名外连接串还支持一组查询参数详见本文第五节例如sqlite://todos.db?moderwc表示“以读写模式打开若文件不存在则自动创建”。另外sqlx-cli在执行命令时会自动读取DATABASE_URL环境变量可通过--database-url覆盖或通过.env文件加载见 sqlx-cli/src/opt.rs 的populate_db_url因此后续db create、migrate run命令无需重复传参。二、创建数据库sqlx db create设置好DATABASE_URL后创建数据库文件$ sqlx db create该命令属于sqlx-cli的Database子命令组CLI 层提供db别名其定义位于 sqlx-cli/src/opt.rs。DatabaseCommand枚举还包括drop删除数据库默认需要交互确认可用-y跳过、reset先删后建并执行待运行迁移与setup创建数据库并执行待运行迁移。对于 SQLitesqlx db create实际效果是创建出DATABASE_URL指向的数据库文件。值得留意的是 ConnectOpts 中的--sqlite-create-db-wal选项默认开启由sqlx-cli创建的 SQLite 数据库默认启用WALWrite-Ahead Log模式。如果应用在SqliteConnectOptions上把journal_mode设为其他值连接时就需要把数据库文件移出 WAL 模式这会要求排他锁并可能触发database is lockedSQLITE_BUSY错误——这是 SQLite 项目里一个常见的坑。三、执行迁移sqlx migrate run创建数据库后把迁移脚本应用到数据库$ sqlx migrate run迁移文件按版本号升序应用。本示例的迁移脚本 20200718111257_todos.sql 内容如下CREATE TABLE IF NOT EXISTS todos ( id INTEGER PRIMARY KEY NOT NULL, description TEXT NOT NULL, done BOOLEAN NOT NULL DEFAULT 0 );文件名20200718111257是时间戳版本号YYYYMMDDHHMMSS格式。MigrateCommand见 sqlx-cli/src/opt.rs还提供了一组配套命令命令用途sqlx migrate add 描述生成新迁移文件--reversible生成一对.up.sql/.down.sql--timestamp/--sequential控制版本号策略见 AddMigrationOptssqlx migrate run应用所有待运行的迁移--dry-run只列出不执行--target-version可指定应用到的版本sqlx migrate revert回滚最近一次迁移依赖.down.sql文件--target-version 0可全部回滚sqlx migrate info列出所有可用迁移及其应用状态sqlx migrate build-script生成build.rs在新增迁移时触发 Cargo 重编译迁移源目录默认为migrations/也可通过--source或sqlx.toml配置修改见 MigrationSourceOpt。SQLx 在数据库端维护迁移记录表遇到“版本号小于已应用迁移”的情况会中止执行因此迁移应始终按递增版本创建。四、运行示例三个核心操作迁移完成后即可编译运行。示例支持三条命令1. 新增一条 TODOcargo run -- add todo description2. 将某条 TODO 标记为完成cargo run -- done todo id3. 列出所有 TODOcargo run对照 examples/sqlite/todos/src/main.rsCLI 结构由clap的 derive 宏声明ArgsSubcommand共两条子命令Add { description: String }与Done { id: i64 }不传子命令时走“列出所有”分支#[derive(Parser)] struct Args { #[command(subcommand)] cmd: OptionCommand, } #[derive(Subcommand)] enum Command { Add { description: String }, Done { id: i64 }, }入口函数用SqlitePool::connect(env::var(DATABASE_URL)?)建立连接池再按子命令分发。注意SQLx 的连接池是惰性建立的——connect只创建池并验证首个连接真正的连接在首次查询时才按需创建。三个业务函数分别对应三种 SQL 形态全部使用query!宏做编译期检查新增add_todo——插入后取回新行的自增 IDlet id sqlx::query!( r# INSERT INTO todos ( description ) VALUES ( ?1 ) #, description ) .execute(mut *conn) .await? .last_insert_rowid();这里用?1作为位置占位符SQLite 风格并调用pool.acquire()从连接池借出连接mut *conn执行last_insert_rowid()是 SQLite 查询结果特有的方法用于获取INTEGER PRIMARY KEY自增列的值。完成complete_todo——更新后判断受影响行数let rows_affected sqlx::query!( r# UPDATE todos SET done TRUE WHERE id ?1 #, id ) .execute(pool) .await? .rows_affected(); Ok(rows_affected 0)execute(pool)直接从池中取一个连接执行rows_affected() 0用于区分“更新成功”与“id 不存在”对应主程序中Todo {id} is marked as done与Invalid id {id}两种输出。列举list_todos——查询并按 id 排序输出let recs sqlx::query!( r# SELECT id, description, done FROM todos ORDER BY id # ) .fetch_all(pool) .await?; for rec in recs { println!( - [{}] {}: {}, if rec.done { x } else { }, rec.id, rec.description, ); }query!宏会在编译期根据DATABASE_URL连接数据库并解析 SQL生成强类型的记录结构rec.id、rec.description、rec.done的类型均由数据库列类型推导此处分别对应i64、String、bool任何 SQL 语法错误、表/列名错误或类型不匹配都会在cargo build阶段直接报错而不是等到运行时。这也是 SQLx “compile-time checked queries without a DSL” 的核心卖点。说明query!的编译期检查需要访问数据库。若在离线环境或 CI 中编译可先用sqlx prepare生成查询元数据缓存到.sqlx目录再通过设置SQLX_OFFLINE值为true或1或移除DATABASE_URL让编译只读取缓存该行为定义见 sqlx-cli/src/opt.rs 中Prepare命令的文档注释。五、纵深SQLite 连接串参数解析掌握了示例的完整流程后再看 SQLite 连接串的底层解析能帮你应对真实项目里的各种连接需求。SQLx 的SqliteConnectOptions遵循 SQLite URI 约定支持以下查询参数参数取值含义modero/rw/rwc/memoryro只读rw读写默认rwc读写且文件不存在时自动创建memory纯内存数据库配合cacheshared可在进程内跨连接共享cacheprivate/shared同一进程内多个连接是否共享缓存内存数据库跨连接持久化数据必须用sharedimmutabletrue/1或false/0声明数据库文件不可变允许 SQLite 跳过一些文件锁检查vfs任意字符串指定虚拟文件系统VFS实现例如sqlite://?modememory与sqlite://:memory:都表示内存数据库sqlite://a.db?modero以只读方式打开sqlite://a.db?cacheshared开启共享缓存。这些写法在该文件末尾的单元测试中均有覆盖sqlx-sqlite/src/options/parse.rs。文件名中的?、#等特殊字符会先做百分号解码percent_decode_str确保路径解析不受干扰未知参数则会直接报配置错误。在SqliteConnectOptions层面默认行为是moderwccreate_if_missing true即直接用SqlitePool::connect(sqlite:todos.db)也会在文件不存在时创建它而sqlx-cli的db create命令则显式负责建库这一步让“结构管理”与“应用逻辑”职责分离。六、小结与延伸回顾整个示例SQLx SQLite 的典型工作流是声明DATABASE_URL→sqlx db create建库 →sqlx migrate run应用结构变更 → 在代码中用query!宏编写受编译期保护的查询 →cargo run运行。如果你需要对比其他数据库仓库中还有结构完全一致的 examples/mysql/todos/README.md 与 examples/postgres/todos只是DATABASE_URL换成mysql://user:passwordhost/db或postgres://user:passwordhost/db形式示例目录同样包含migrations/、src/main.rs与Cargo.toml三者的 CLI 用法完全相同——这说明 SQLx 的query!宏与sqlx-cli在工作流层面是跨数据库统一的。从本示例出发你可以进一步阅读 sqlx-cli 源码 了解全部子命令或参考 sqlx-core 的迁移模块 探究迁移记录与版本校验的内部实现。赞分享数据库后端【免费下载链接】sqlx The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, and SQLite.项目地址https://gitcode.com/gh_mirrors/sql/sqlx点击查看免费下载相关推荐基于 SQLx 与 MySQL 的编译期校验 TODO 应用实战从数据库迁移到 query! 宏基于 SQLx 与 MySQL 的编译期校验 TODO 应用实战从数据库迁移到 query! 宏 本指南围绕仓库中的 MySQL 示例应用 examples/数据库后端pgx 实战用 PostgreSQL 官方驱动构建一个命令行 Todo 应用examples/todo 全解析pgx 实战用 PostgreSQL 官方驱动构建一个命令行 Todo 应用examples/todo 全解析 本篇技术指南以 pgx 仓库自带的 exa数据库后端使用 SQLx 与 PostgreSQL 从零构建命令行 Todo 应用完整示例解析使用 SQLx 与 PostgreSQL 从零构建命令行 Todo 应用完整示例解析 导读 本文以 SQLx 官方示例 examples/postgres/t数据库后端上一篇NanoClaw 系统规范深度解读容器隔离的多通道个人 AI 助手架构v1 历史规范与 v2 演进对照下一篇PTO A5 平台 TGET_ASYNC RDMA 异步 ST 测试指南远程 READ 的验证实现与端点发现原理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考