Introduction
Toasty is an async ORM for Rust. It supports both SQL databases (SQLite/Turso, PostgreSQL, MySQL) and NoSQL databases (DynamoDB).
You define your models as Rust structs and annotate them with
#[derive(toasty::Model)]. Toasty infers the database schema from your
annotated structs — field types map to column types, and attributes like
#[key], #[unique], and #[index] control the schema. You can customize the
mapping with attributes for table names, column names, and column types. Toasty’s
derive macro also generates query builders, create/update/upsert builders, and
relationship accessors at compile time.
#![allow(unused)]
fn main() {
use toasty::Model;
#[derive(Debug, toasty::Model)]
struct User {
#[key]
#[auto]
id: u64,
name: String,
#[unique]
email: String,
}
}
From this definition, Toasty generates:
toasty::create!(User { ... })— insert new usersUser::get_by_id()— fetch a user by primary keyUser::get_by_email()— fetch a user by the unique email fieldUser::all()— query all usersuser.update()— a builder for modifying a useruser.delete()— remove a userUser::fields()— field accessors for building filter expressions
The rest of this guide walks through each feature with examples. By the end, you will know how to define models, set up relationships, query data, and use Toasty’s more advanced features like embedded types, batch operations, and transactions.
What this guide covers
- Getting Started — set up a project and run your first query
- Defining Models — struct fields, types, and table mapping
- Keys and Auto-Generation — primary keys, auto-generated values, composite keys
- Creating Records — insert one or many records
- Querying Records — find, filter, and iterate over results
- Updating Records — modify existing records
- Upserting Records — create or update atomically by a key or unique constraint
- Deleting Records — remove records
- Indexes and Unique Constraints — add indexes and unique constraints
- Field Options — column names, types, defaults, and update expressions
- Relationships — overview of how models connect to each other
- BelongsTo — define and use many-to-one relationships
- HasMany — define and use one-to-many relationships
- Many-to-Many — connect two models through a join model
- HasOne — define and use one-to-one relationships
- Preloading Associations — eager loading to avoid extra queries
- Filtering with Expressions — comparisons, AND/OR, and more
- Sorting, Limits, and Pagination — order results and paginate
- Embedded Types — store structs and enums inline
#[document]Fields — store an embedded struct in one document with queryable scalar leaves- JSON Encoding — store a serde type or
serde_json::Valuein one opaque column Vec<scalar>Fields — store and query a scalar collection in one field- Batch Operations — multiple queries in one round-trip
- Transactions — atomic operations
- Database Setup — connection URLs, table creation, and supported databases
- Migrations and Schema Management — create and reset database tables
Runnable example:
quickstart-blogwalks the full create → query → update → delete cycle over ahas_many/belongs_torelationship.