>_ DevTrendszh

语言

首页

语言

板块

前端 后端 移动端 DevOps AI / ML 游戏开发 区块链 嵌入式 安全
Rust

SQLx 改变了 Rust 中的数据库工作方式

想象一下:你写了一个复杂的 SQL 查询,编译了你的 Rust 项目,运行它,然后……得到了一个运行时错误,因为你拼错了列名或忘记传递一个参数。很烦人,对吧?尤其是在一门以安全性著称的编程语言中。这正是 SQLx 要解决的问题。

这东西到底是什么

SQLx 不是像 Hibernate 或 SQLAlchemy 那样典型的 ORM。开发者称它为"SQL 工具包"。这个项目的主要特点是它在编译时验证你的 SQL 查询。如果你在 SELECT 中拼错了或试图在数据库期望数字的地方塞入字符串,Rust 编译器根本不会让你编译二进制文件。

这个项目完全异步且使用纯 Rust 编写(SQLite 驱动除外,它引入了 C 库)。它支持 PostgreSQL、MySQL 和 SQLite。以前有 MSSQL 支持,但在 0.7 版本中被移除了,开发者承诺会从头重写驱动。

编译时查询验证

这可能是这个库最强大的地方。与 Diesel 或 SeaORM 通过方法链(DSL)构建查询不同,你在宏中编写纯 SQL。

它是如何工作的?在构建过程中,SQLx 连接到你的数据库(路径在 DATABASE_URL 环境变量中指定),请求它验证查询,并返回类型信息。如果数据库表示查询正确,宏会生成一个包含结果的结构体。

顺便说一句,如果你不想让 CI 服务器在每次构建时都连接实际的数据库,SQLx 有一个"离线模式"。你只需准备一次包含查询元数据的缓存,然后项目就可以在没有网络连接的情况下构建。

异步性和性能

SQLx 从一开始就是为 async/await 设计的。它不试图模仿用线程包装的同步 API。这个库可以流式处理数据:如果你需要导出一百万行数据,你可以逐个处理从套接字到达的数据,而不会一次性填满所有内存。

有趣的是,这个项目不依赖特定的运行时。你可以使用 tokioasync-stdactix — 只需在 Cargo.toml 中启用所需的特性标志。

为什么它不是 ORM

SQLx 没有"模型"或"关系"这类熟悉的概念。你不在 Rust 代码中描述 User has_many Posts。你在 SQL 查询中描述 JOIN

对于习惯完全控制数据库的人来说,这是一个巨大的优势。你可以使用特定 DBMS 的全部功能:特定的数据类型(如 Postgres 中的 JSONB)、窗口函数或复杂的触发器。SQLx 只负责将结果映射到 Rust 结构体这件繁琐的工作,通过 FromRow derive 宏实现。

小但有用的细节

这个库有很多通常需要在第三方插件中寻找的不错的细节:

  • 内置连接池。无需插入 r2d2 或类似的库。
  • 迁移支持。有一个 CLI 工具和 migrate! 宏,可以将迁移直接嵌入到你的二进制文件中。
  • PostgreSQL 开箱即支持 LISTEN/NOTIFY
  • 事务处理,包括通过保存点的嵌套事务。

值得使用吗

如果你热爱 SQL 并想充分利用数据库的能力,同时又不失去 Rust 的类型安全,SQLx 是完美的选择。

但你用构建时间来换取编译时查询验证。如果你有数百个 query! 宏,cargo check 可能会明显变慢。在这种情况下,开发者建议在开发配置文件中调整宏的优化级别:

如果你需要具有自动查询生成功能的经典 ORM,你最好看看 SeaORM,顺便说一下,它是建立在 SQLx 之上的。

总的来说,这个项目看起来非常成熟。它在 GitHub 上有超过 17,000 颗星和一个活跃的社区。如果你正在启动一个新的 Rust 后端项目,并且不害怕手写 SQL — 它可能是目前最好的选择。

相关项目