
数据库后端【免费下载链接】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 官方示例examples/postgres/todos为主线完整演示如何用 SQLx 的sqlx-cli完成数据库创建与迁移并借助sqlx::query!宏实现编译期检查的 SQL 查询构建一个可新增、完成、列出待办事项的命令行应用。读完本文你将掌握 PostgreSQL SQLx 从环境配置、迁移管理到编译期类型安全的完整实践路径可直接复制这套模式到自己的 Rust 项目中。示例概览与仓库位置该示例位于仓库的 examples/postgres/todos 目录是一个极简但完整的 PostgreSQL 增删查改CRUD命令行程序。它的工程结构非常典型几乎涵盖了一个真实 SQLx 项目的最小骨架Cargo.toml声明依赖与 SQLx feature 组合migrations/20200718111257_todos.sql数据库迁移脚本定义todos表src/main.rs程序入口包含全部查询逻辑README.md官方提供的设置与使用步骤本文即以此为核心展开。从代码结构看示例刻意保持单文件 单迁移的精简形态目的是把 SQLx 最核心的三件事——连接池、迁移、编译期查询宏——浓缩在一个可运行的例子里。环境准备安装 sqlx-cli在开始设置之前先确认本机已安装sqlx-cli因为后续的建库与迁移都依赖它。SQLx 官方推荐用 Cargo 安装安装说明详见 sqlx-cli/README.md# 全量安装支持 SQLx 支持的所有数据库 $ cargo install sqlx-cli # 如果只需要 PostgreSQL可裁剪 feature 以加快编译 $ cargo install sqlx-cli --no-default-features --features native-tls,postgres第二条命令只启用postgres驱动与native-tls传输层安全后端适合本文这种纯 PostgreSQL 场景。另外从 sqlx-cli/src/opt.rs 的ConnectOpts定义可以看出CLI 的所有子命令都支持通过--database-url命令行参数直接指定数据库地址其优先级高于环境变量同时sqlx命令默认会读取当前目录下的.env文件若存在来加载DATABASE_URL。第一步声明数据库连接地址示例要求先通过环境变量声明数据库 URLexport DATABASE_URLpostgres://postgres:passwordlocalhost/todos这个 URL 的组成遵循 PostgreSQL 标准连接串格式postgres://用户名:密码主机:端口/数据库名。这里连接的用户是postgres、密码为password、目标主机为本地localhost、目标数据库为todos。值得说明的是DATABASE_URL在 SQLx 中承担着双重角色运行时角色程序通过env::var(DATABASE_URL)读取它来建立连接池见 src/main.rs编译期角色sqlx::query!宏在编译时连接该数据库以校验 SQL 语法与类型详见下文编译期检查一节。因此在设置数据库之前就导出该变量能确保后续的sqlx db create、sqlx migrate run以及cargo run使用同一个目标。除了环境变量也可以使用--database-url选项替代如sqlx db create --database-url postgres://...或将变量写入当前目录的.env文件dotenvy会在启动时自动加载——示例的 Cargo.toml 中正是通过依赖dotenvy 0.15.7来支持.env文件的。第二步创建数据库$ sqlx db createsqlx db create会根据DATABASE_URL中指定的数据库名在目标 PostgreSQL 服务器上创建对应的数据库本示例即创建名为todos的数据库。查看 sqlx-cli/src/database.rs 的create函数实现可以发现几个实用细节命令是幂等的它会先检查数据库是否已存在只有不存在时才真正执行创建它通过 SQLx 的Any驱动与MigrateDatabase::create_database完成跨数据库适配因此同样的命令也适用于 MySQL/SQLite 等其他后端。与此配套的还有几个常用命令对应 sqlx-cli/src/opt.rs 中DatabaseCommand枚举# 删除数据库会弹出确认提示可用 -y 跳过 $ sqlx db drop # 删除后重建并运行所有待执行的迁移 $ sqlx db reset # 创建数据库并直接运行所有迁移一步到位 $ sqlx db setup第三步运行数据库迁移$ sqlx migrate run该命令会对比当前数据库的迁移记录与migrations/目录下的迁移文件把尚未应用的迁移按版本号升序逐一执行。本示例只有一个迁移文件 migrations/20200718111257_todos.sql内容如下CREATE TABLE IF NOT EXISTS todos ( id BIGSERIAL PRIMARY KEY, description TEXT NOT NULL, done BOOLEAN NOT NULL DEFAULT FALSE );这张表的设计与示例的三个命令一一对应id BIGSERIAL PRIMARY KEYPostgreSQL 自增主键add命令插入后通过RETURNING id取回description TEXT NOT NULL待办描述文本对应add todo description的参数done BOOLEAN NOT NULL DEFAULT FALSE完成状态done命令将其置为TRUE。关于迁移机制sqlx-cli/src/migrate.rs 中的run函数揭示了底层保障每个迁移文件以版本号_描述.sql命名如20200718111257_todos.sql版本号是YYYYMMDDHHMMSS格式的时间戳见 sqlx-cli/src/opt.rs 的next_timestamp()迁移执行前会先检查是否存在脏迁移记录dirty_version若存在则中止防止迁移中断后继续误操作已应用迁移的校验和会与本地文件比对VersionMismatch检查本地修改了已应用的迁移文件会被检测出来迁移记录存放在数据库内部的迁移表中SQLx 通过ensure_migrations_table自动维护。如果在生产环境使用sqlx-cli还提供sqlx migrate info查看迁移状态、sqlx migrate revert回滚需使用-r创建的可逆迁移、以及--dry-run预演等能力详见 sqlx-cli/README.md。使用示例三个命令的实战演示迁移完成后示例程序即可运行。它基于clap的子命令解析见 src/main.rs共支持三个子命令。新增一条待办cargo run -- add todo description对应代码中的add_todo函数src/main.rsasync fn add_todo(pool: PgPool, description: String) - anyhow::Resulti64 { let rec sqlx::query!( r# INSERT INTO todos ( description ) VALUES ( $1 ) RETURNING id #, description ) .fetch_one(pool) .await?; Ok(rec.id) }这里集中体现了 SQLx 的两个设计要点占位符绑定PostgreSQL 使用$1、$2形式的占位符MySQL 则用?description作为参数传入由驱动以参数化查询方式发送从机制上规避 SQL 注入RETURNING 子句利用 PostgreSQL 的RETURNING id在一次往返中拿到新插入记录的自增主键无需额外的SELECT。标记一条待办为已完成cargo run -- done todo id对应complete_todo函数src/main.rsasync fn complete_todo(pool: PgPool, id: i64) - anyhow::Resultbool { 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终结器返回QueryResult其rows_affected()给出受影响行数更新成功返回true若传入不存在的id则返回false主程序据此打印Invalid id {id}见 src/main.rs。列出全部待办cargo run不带子命令时程序调用list_todossrc/main.rsasync fn list_todos(pool: PgPool) - anyhow::Result() { 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, ); } Ok(()) }输出采用类似 Markdown 任务列表的格式未完成显示- [ ] id: description已完成显示- [x] id: description。编译期检查的查询query! 宏的底层原理上述三个查询全部使用sqlx::query!宏这是 SQLx 区别于传统 ORM/驱动层的核心能力。其工作原理仓库根 README.md 有权威说明是宏在编译期连接DATABASE_URL指向的开发数据库把 SQL 原文发送给数据库解析与描述prepare由数据库本身验证语法和语义验证通过后宏根据返回的列元数据生成一个匿名记录类型每个 SQL 列对应一个类型正确的 Rust 字段。例如SELECT id, description, done会生成形如{ id: i64, description: String, done: bool }的类型绑定参数的数量与类型同样在编译期被校验参数个数不匹配或类型错误会直接导致编译失败而不是等到运行时才暴露。正因如此示例中rec.done、rec.id、rec.description都能获得与数据库列类型严格对应的 Rust 类型bool、i64、String并且在编译时就被保证了字段的存在性。这一点也解释了为什么示例必须事先完成建库 迁移宏需要连接一个与运行时同构同类型、同 schema的数据库来校验查询。编译期校验带来的一个实际体验是cargo build会变慢官方建议在Cargo.toml中为宏所在的 crate 开启优化见根 README.md[profile.dev.package.sqlx-macros] opt-level 3另外若希望在没有开发数据库的环境中编译如 CI可以使用cargo sqlx prepare生成查询元数据缓存配合SQLX_OFFLINEtrue进入离线模式详见 sqlx-cli/README.md。依赖与 Feature 配置解析示例的 Cargo.toml 是理解 SQLx 依赖配置的绝佳范本[package] name sqlx-example-postgres-todos version 0.1.0 edition 2018 workspace ../../../ [dependencies] anyhow 1.0.58 sqlx { path ../../../, features [ postgres, runtime-tokio, tls-native-tls ] } clap { version 4.4.7, features [derive] } tokio { version 1.25.0, features [rt, macros]} dotenvy 0.15.7其中sqlx依赖的 feature 组合值得逐项说明官方说明见根 README.md 与 README.mdFeature作用postgres启用 PostgreSQL 数据库驱动支持runtime-tokio使用 Tokio 异步运行时不含 TLS 后端tls-native-tls启用 native-tls 传输层安全后端*nix 下基于 OpenSSLSQLx 要求运行时与 TLS 两个维度都必须有选择运行时可选runtime-tokio/runtime-async-stdTLS 可选tls-native-tls/tls-rustls含不同变体。sqlx::query!宏属于macrosfeature但示例并未显式开启——从根 README.md 可知macros由sqlx默认启用因此query!开箱即用。其余依赖各司其职tokiofeatures 含rt、macros提供异步运行时配合#[tokio::main(flavor current_thread)]属性见 src/main.rs启动单线程异步主函数clapderive 特性基于派生宏生成子命令参数解析器dotenvy加载.env文件让DATABASE_URL可以不显式导出也能被读取anyhow提供便捷的错误传播与上下文包装。连接池PgPool 的建立与使用主程序通过一行代码建立连接池src/main.rslet pool PgPool::connect(env::var(DATABASE_URL)?).await?;PgPool是sqlx::Pool在 PostgreSQL 上的类型别名。相比单条连接PgConnection::connect连接池会维护一组可复用的连接由池内部统一调度从而避免每次查询都新建 TCP 连接的开销并天然支持高并发场景。三个查询函数都以PgPool作为执行器参数SQLx 的Executortrait 对Pool与mut Connection均有实现因此同一个函数签名既适用于池也适用于连接。完整上手流程速查将以上内容串联起来一个从零到可运行的最小流程是# 0. 安装 CLI如未安装 cargo install sqlx-cli --no-default-features --features native-tls,postgres # 1. 进入示例目录 cd examples/postgres/todos # 2. 声明数据库地址 export DATABASE_URLpostgres://postgres:passwordlocalhost/todos # 3. 创建数据库 sqlx db create # 4. 应用迁移建表 sqlx migrate run # 5. 使用 cargo run -- add write a blog post cargo run -- done 1 cargo run输出示例cargo run列出Printing list of all todos - [x] 1: write a blog post延伸把示例模式迁移到自己的项目如果要把这套连接池 迁移 query!的模式复用到自己的项目中可以按下面三步对齐依赖声明复制示例的sqlxfeature 组合postgres、runtime-tokio、tls-native-tls并按需补充macros、migrate、chrono、uuid等特性迁移目录在项目根创建migrations/目录用sqlx migrate add 描述生成带时间戳的迁移文件参考 sqlx-cli/README.md并在 CI 或部署流程中调用sqlx migrate run查询编写始终把 SQL 写在sqlx::query!/query_as!中利用编译期校验尽早发现列名、类型与参数问题若希望输出类型可命名可使用query_as!配合自定义struct详见根 README.md。需要说明的是sqlx db create在 PostgreSQL 场景下要求连接 URL 中的用户名具备建库权限且示例默认连接本地localhost:5432若你的 PostgreSQL 监听在非默认端口或使用了不同认证方式请相应调整DATABASE_URL。本文所有结论均基于当前仓库中示例源码、迁移脚本与 CLI 实现可直接对照 examples/postgres/todos/src/main.rs、examples/postgres/todos/migrations/20200718111257_todos.sql 与 sqlx-cli/src/migrate.rs 逐行验证。赞分享数据库后端【免费下载链接】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点击查看免费下载相关推荐pgx 实战用 PostgreSQL 官方驱动构建一个命令行 Todo 应用examples/todo 全解析pgx 实战用 PostgreSQL 官方驱动构建一个命令行 Todo 应用examples/todo 全解析 本篇技术指南以 pgx 仓库自带的 exa数据库后端mmdetection 中 DCNv2可变形卷积 v2的配置与实战从 mdconv 到 mdpool 的完整使用指南mmdetection 中 DCNv2可变形卷积 v2的配置与实战从 mdconv 到 mdpool 的完整使用指南 本文以 configs/dcnv2/数据库后端Recoil实战案例构建完整的Todo应用示例Recoil实战案例构建完整的Todo应用示例 Recoil作为Facebook开发的实验性React状态管理库为开发者提供了比React内置状态管理更强大前端上一篇SerenityOS 中 setresuid/setresgid 的实现解析真实、有效与保存的 UID/GID 系统调用下一篇PostHog 安全审计 Skill面向 SaaS 多租户系统的校准式 AI 安全审计工作流创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考