#orm #sql-database #sql-query #sql

butane

一个以简洁性和Rust编写而非SQL为重点的ORM

14个版本

0.7.0 2024年7月17日
0.6.1 2023年5月27日
0.5.1 2022年12月27日
0.5.0 2022年11月14日
0.1.0 2020年12月29日

#182数据库接口

Download history 1/week @ 2024-04-25 2/week @ 2024-05-30 5/week @ 2024-06-06 2/week @ 2024-06-13 2/week @ 2024-06-20 1/week @ 2024-06-27 84/week @ 2024-07-11 52/week @ 2024-07-18 8/week @ 2024-07-25 3/week @ 2024-08-01

147 每月下载量
用于 2 crates

MIT/Apache

285KB
6.5K SLoC

Latest Version docs Build Status

Butane

一个专注于简洁性和Rust编写而非SQL的实验性Rust ORM

Butane采用面向对象的方法进行数据库操作。它可以被视为一个对象持久化系统,而不仅仅是一个ORM -- 事实是它由SQL数据库支持,对API消费者来说主要是实现细节。

功能

  • 使用类似Rust语法的关联查询(通过proc-macro
  • 自动迁移,无需编写SQL(尽管必要时可以手动调整生成的SQL)
  • 能够在Rust代码中嵌入迁移(以便库可以轻松捆绑其迁移)
  • SQLite和PostgreSQL后端
  • 无论数据库后端如何,都可以编写全部或几乎全部相同的代码

入门

模型,使用结构体属性声明定义数据库模式。例如,一个博客的Post模型可能看起来像这样

#[model]
#[derive(Default)]
struct Post {
    id: AutoPk<i32>,
    title: String,
    body: String,
    published: bool,
    likes: i32,
    tags: Many<Tag>,
    blog: ForeignKey<Blog>,
    byline: Option<String>,
}

一个对象模型的实例。对象创建的方式与普通的结构体实例一样,但必须保存才能持久化。

let mut post = Post::new(blog, title, body);
post.save(conn)?;

只有在保存时才会将实例的更改应用到数据库

post.published = true;
post.save(conn)?;

查询通过query!宏以人体工程学的方式执行。

let posts = query!(Post, published == true).limit(5).load(&conn)?;

有关详细教程,请参阅入门指南

Cargo功能

Butane向Cargo公开了几个功能。默认情况下,不启用任何后端:您将希望启用sqlite和/或pg

  • default:启用datetimejsonuuid
  • debug:用于Butane的开发,消费者通常不期望启用。
  • datetime:支持时间戳(使用chrono crate)。
  • fake:支持fake crate的伪造数据生成。
  • json:支持将结构体存储为JSON,包括使用PostgreSQL的JSONB字段类型。
  • log:将某些警告记录到log crate的包装器(目标 "butane")。
  • pg:使用postgres crate支持PostgreSQL。
  • r2d2:使用 r2d2 支持的连接池(参见 butane::db::ConnectionManager)。
  • sqlite:使用 rusqlite 包支持 SQLite。
  • sqlite-bundled:使用打包的 sqlite 而不是系统版本。
  • tls:使用 PostgreSQL 时支持 TLS,使用 postgres-native-tls 包。
  • uuid:支持 UUID(使用 uuid 包)。

限制

  • Butane,特别是其迁移系统,期望拥有数据库。它可以与由其他消费者访问的现有数据库一起使用,但这不是设计目标,也没有从现有数据库模式推断 Butane 模型的工具。
  • API 的人性化胜过性能。这并不意味着 Butane 很慢,而是在简单直接的 API 和最小化开销之间做出选择时,API 将获胜。

路线图

Butane 仍处于早期阶段。以下功能目前尚未实现,但计划中

  • 外键约束级联设置
  • 增量对象保存
  • ForeignKeyMany 提供反向引用。
  • 迁移中支持字段/列重命名
  • 准备/可重用查询
  • 基准测试和性能调整
  • 对 MySQL 或 SQL Server 等其他数据库的支持没有明确计划,但欢迎贡献。

与 Diesel 的比较

Butane 受 Diesel 和 Django ORM 的启发。如果您在寻找成熟、高性能且灵活的 ORM,请使用 Diesel。Butane 并不旨在优于 Diesel,但做出了一些 不同 的决定,包括

  1. 它更面向对象,但牺牲了一些灵活性。

  2. 优先考虑自动迁移。

  3. Rust 代码是真相的来源。模式是通过 Rust 代码中模型的定义来理解的,而不是从数据库中推断出来的。

  4. 查询是在 proc-macro 调用内部的 DSL 中构建的,而不是通过导入 DSL 方法/名称到当前作用域中来使用。对于 Diesel,您可能这样写

    use diesel_demo::schema::posts::dsl::*;
    let posts = posts.filter(published.eq(true))
         .limit(5)
         .load::<Post>(&conn)?
    

    而对于 Butane,您将改写为

    let posts = query!(Post, published == true).limit(5).load(&conn)?;
    

    哪种形式更可取主要是一种审美判断。

  5. 数据库后端之间的差异在很大程度上被隐藏了。

  6. Diesel 总体上更为成熟且功能更全面。

有关详细教程,请参阅 入门指南

许可

Butane 可选择在 MIT 许可证Apache 许可证 2.0 下使用。

除非您明确表示,否则根据 Apache-2.0 许可证定义的,您有意提交给 Butane 的任何贡献都应双许可,没有附加条款或条件。

依赖关系

~4–22MB
~320K SLoC