#orm #async #sql #sql-orm

sqlmodel

SQL databases in Rust, designed to be intuitive and type-safe

2 unstable releases

Uses new Rust 2024

new 0.2.0 Feb 15, 2026
0.1.1 Feb 5, 2026

#2235 in Database interfaces

MIT license

1.5MB
39K SLoC

sqlmodel

Facade crate for SQLModel Rust; re-exports the full ORM stack behind a single dependency.

Role in the SQLModel Rust System

  • Primary user-facing entry point (prelude, macros, query builders, schema tools).
  • Glue layer over sqlmodel-core, sqlmodel-macros, sqlmodel-query, sqlmodel-schema, sqlmodel-session, sqlmodel-pool.
  • Optional console integration via the console feature.

Usage

Most users should depend on sqlmodel and import from sqlmodel::prelude::*. Use this crate directly if you are extending internals or building tooling around the core APIs.


lib.rs:

SQLModel Rust - SQL databases in Rust, designed to be intuitive and type-safe.

sqlmodel is the facade crate for the entire SQLModel Rust ecosystem. It re-exports the core traits, macros, query builders, schema/migration tooling, session layer, pooling, and optional console integration so most applications only need a single dependency.

Role In The Architecture

  • One-stop import: use sqlmodel::prelude::*; gives you Model, Connection, Expr, and the query macros.
  • Facade over sub-crates: wraps sqlmodel-core, sqlmodel-macros, sqlmodel-query, sqlmodel-schema, sqlmodel-session, and sqlmodel-pool.
  • Optional console: feature-gated integration with sqlmodel-console for rich output.

When To Use This Crate

Use sqlmodel for nearly all application code. Reach for the sub-crates directly only if you're extending internals or building an alternative facade.

Quick Start

use sqlmodel::prelude::*;

#[derive(Model, Debug)]
#[sqlmodel(table = "heroes")]
struct Hero {
    #[sqlmodel(primary_key, auto_increment)]
    id: Option<i64>,
    name: String,
    secret_name: String,
    age: Option<i32>,
}

async fn main_example(cx: &Cx, conn: &impl Connection) -> Outcome<(), Error> {
    let hero = Hero {
        id: None,
        name: "Spider-Man".to_string(),
        secret_name: "Peter Parker".to_string(),
        age: Some(25),
    };

    let _id = match insert!(hero).execute(cx, conn).await {
        Outcome::Ok(v) => v,
        Outcome::Err(e) => return Outcome::Err(e),
        Outcome::Cancelled(r) => return Outcome::Cancelled(r),
        Outcome::Panicked(p) => return Outcome::Panicked(p),
    };

    let heroes = match select!(Hero)
        .filter(Expr::col("age").gt(18))
        .all(cx, conn)
        .await
    {
        Outcome::Ok(v) => v,
        Outcome::Err(e) => return Outcome::Err(e),
        Outcome::Cancelled(r) => return Outcome::Cancelled(r),
        Outcome::Panicked(p) => return Outcome::Panicked(p),
    };

    let Some(mut hero) = heroes.into_iter().next() else {
        return Outcome::Ok(());
    };
    hero.age = Some(26);

    match update!(hero).execute(cx, conn).await {
        Outcome::Ok(_) => {}
        Outcome::Err(e) => return Outcome::Err(e),
        Outcome::Cancelled(r) => return Outcome::Cancelled(r),
        Outcome::Panicked(p) => return Outcome::Panicked(p),
    };

    match delete!(Hero)
        .filter(Expr::col("name").eq("Spider-Man"))
        .execute(cx, conn)
        .await

    {
        Outcome::Ok(_) => Outcome::Ok(()),
        Outcome::Err(e) => Outcome::Err(e),
        Outcome::Cancelled(r) => Outcome::Cancelled(r),
        Outcome::Panicked(p) => Outcome::Panicked(p),
    }
}

Features

  • Zero-cost abstractions: Compile-time code generation, no runtime reflection
  • Structured concurrency: Built on asupersync for cancel-correct operations
  • Type safety: SQL types mapped to Rust types with compile-time checks
  • Fluent API: Chainable query builder methods
  • Connection pooling: Efficient connection reuse
  • Migrations: Version-controlled schema changes
  • console feature: Enable rich terminal output via sqlmodel-console

Dependencies

~27–44MB
~674K SLoC