#orm #mysql #postgresql

rbdc

The Rust SQL Toolkit and ORM Library. An async, pure Rust SQL crate featuring compile-time Dynamic SQL

54 stable releases

Uses new Rust 2024

4.9.10 May 3, 2026
4.7.1 Mar 26, 2026
4.6.2 Nov 2, 2025
4.6.0 May 22, 2025
0.1.22 Sep 15, 2022

#2754 in Database interfaces

Download history 521/week @ 2026-02-06 400/week @ 2026-02-13 628/week @ 2026-02-20 727/week @ 2026-02-27 819/week @ 2026-03-06 998/week @ 2026-03-13 973/week @ 2026-03-20 719/week @ 2026-03-27 553/week @ 2026-04-03 922/week @ 2026-04-10 765/week @ 2026-04-17 759/week @ 2026-04-24 939/week @ 2026-05-01 631/week @ 2026-05-08 592/week @ 2026-05-15 596/week @ 2026-05-22

2,823 downloads per month
Used in 50 crates (23 directly)

Apache-2.0

185KB
5K SLoC

rbdc

Crates.io Documentation License

Database driver abstraction layer for Rust, providing a unified interface for rbatis.

Table of Contents

Features

  • Safe: #![forbid(unsafe_code)] - 100% safe Rust
  • Async: Native async support based on Tokio
  • Extensible: Simple trait definitions for easy driver implementation

Supported Databases

Database Driver
MySQL rbdc-mysql
PostgreSQL rbdc-pg
SQLite rbdc-sqlite
MSSQL rbdc-mssql
Truso rbdc-turso
DuckDB rbdc-duckdb

Quick Start

use rbdc_sqlite::SqliteDriver;
use rbdc_pool_fast::FastPool;

#[tokio::main]
async fn main() -> Result<(), rbdc::Error> {
    let pool = FastPool::new_url(SqliteDriver {}, "sqlite://target/test.db")?;
    let mut conn = pool.get().await?;
    let v = conn.exec_decode("SELECT * FROM sqlite_master", vec![]).await?;
    println!("{}", v);
    // if need decode use `let result: Vec<Table> = rbs::from_value(v)?;`
    Ok(())
}

Scan Utility

For memory-efficient row-by-row iteration instead of loading all rows into a Value array at once:

use rbdc::db::Connection;
use rbdc::util::Scan;

let rows = conn.exec_rows("SELECT * FROM activity", vec![]).await?;
let scan = Scan::new(rows);

// Collect all rows into a Vec of struct
#[derive(serde::Deserialize)]
struct Activity {
    id: Option<String>,
    name: Option<String>,
}
let activities: Vec<Activity> = scan.collect()?;

Implement Custom Driver

Implement these 6 traits:

use rbdc::db::{Driver, MetaData, Row, Connection, ConnectOptions, Placeholder};

impl Driver for YourDriver {}
impl MetaData for YourMetaData {
    // TODO: impl methods
}
impl Row for YourRow {
    // TODO: impl methods
}
impl Connection for YourConnection {
    // TODO: impl methods
}
impl ConnectOptions for YourConnectOptions {
    // TODO: impl methods
}
impl Placeholder for YourPlaceholder {
    // TODO: impl methods
}

/// use your driver
#[tokio::main]
async fn main() -> Result<(), rbdc::Error> {
    let uri = "YourDriver://****";
    let pool = FastPool::new_url(YourDriver {}, uri)?;
    let mut conn = pool.get().await?;
    let v = conn.exec_decode("SELECT 1", vec![]).await?;
    println!("{}", v);
}

For databases with blocking APIs, refer to rbdc-sqlite which uses the flume channel library.

See examples for more.

License

MIT

Dependencies

~7–23MB
~318K SLoC