drizzle-migrations 0.1.10

Migration infrastructure for drizzle-rs
Documentation

Drizzle Migrations - DDL and migration infrastructure for drizzle-rs

This crate provides:

  • migration discovery (MigrationDir)
  • runtime tracking config (Tracking)
  • pure diff APIs (diff, diff_schemas_with)
  • build-time migration generation (build::run)

Recommended No-CLI Flow

  1. In build.rs, keep ./drizzle up to date:
# fn main() -> Result<(), Box<dyn std::error::Error>> {
use drizzle_migrations::build::{Config, Output, run};
use drizzle_types::Dialect;

let cfg = Config::new(Dialect::SQLite)
    .file("./src/schema.rs")
    .out("./drizzle");

// Registers schema files as build.rs inputs.
cfg.watch();

match run(&cfg)? {
    Output::NoChanges => {}
    Output::Generated { tag, .. } => {
        println!("cargo:warning=generated migration {tag}");
    }
}
# Ok(())
# }
  1. In app code, embed and run migrations:
# use drizzle_migrations::{Migration, Tracking};
# fn main() -> Result<(), Box<dyn std::error::Error>> {
# struct Db;
# impl Db {
#     fn migrate(&self, _migrations: &[Migration], _config: Tracking) -> Result<(), Box<dyn std::error::Error>> {
#         Ok(())
#     }
# }
# let db = Db;
// Usually produced by: `drizzle::include_migrations!("./drizzle")`
let migrations: Vec<Migration> = Vec::new();
db.migrate(&migrations, Tracking::SQLITE)?;
# Ok(())
# }

Runtime Generation APIs (No CLI)

Use these when you need runtime diffing between two inputs.

Snapshot-to-snapshot

use drizzle_migrations::{Snapshot, diff};

let prev = Snapshot::empty(drizzle_types::Dialect::SQLite);
let current = Snapshot::empty(drizzle_types::Dialect::SQLite);
let migration = diff(&prev, &current).unwrap();
assert!(migration.statements.is_empty());

Schema-to-schema with rename hints

use drizzle_migrations::{Options, Schema, Snapshot, diff_schemas_with};
use drizzle_types::Dialect;

# #[derive(Default)]
# struct AppSchemaV1;
# #[derive(Default)]
# struct AppSchemaV2;
# impl Schema for AppSchemaV1 {
#     fn to_snapshot(&self) -> Snapshot { Snapshot::empty(Dialect::SQLite) }
#     fn dialect(&self) -> Dialect { Dialect::SQLite }
# }
# impl Schema for AppSchemaV2 {
#     fn to_snapshot(&self) -> Snapshot { Snapshot::empty(Dialect::SQLite) }
#     fn dialect(&self) -> Dialect { Dialect::SQLite }
# }
let migration = diff_schemas_with(
    &AppSchemaV1,
    &AppSchemaV2,
    &Options::new()
        .rename_table("users_old", "users")
        .rename_column("users", "full_name", "name")
        .strict_renames(true),
)?;
# let _ = migration;
# Ok::<(), drizzle_migrations::MigrationError>(())

CLI Usage

For generating migrations, use the drizzle-cli crate:

# Install
cargo install drizzle-cli

# Initialize config
drizzle init --dialect sqlite

# Generate migrations
drizzle generate

# Run migrations
drizzle migrate