{"id":17648548,"url":"https://github.com/cljoly/rusqlite_migration","last_synced_at":"2026-04-01T22:20:19.673Z","repository":{"id":37247169,"uuid":"310963872","full_name":"cljoly/rusqlite_migration","owner":"cljoly","description":"↕️ Simple database schema migration library for rusqlite, written with performance in mind.","archived":false,"fork":false,"pushed_at":"2026-03-21T22:06:25.000Z","size":521,"stargazers_count":106,"open_issues_count":7,"forks_count":30,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-03-22T10:40:40.175Z","etag":null,"topics":["hacktoberfest","library","rusqlite","rust","schema","sqlite3"],"latest_commit_sha":null,"homepage":"https://cj.rs/rusqlite_migration/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cljoly.png","metadata":{"funding":{"custom":["https://cj.rs/donate/"]},"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-11-08T01:29:23.000Z","updated_at":"2026-03-21T22:06:28.000Z","dependencies_parsed_at":"2024-05-18T22:25:53.102Z","dependency_job_id":"a7a1a8ad-9cb4-4513-85b4-fd2b34bfc61f","html_url":"https://github.com/cljoly/rusqlite_migration","commit_stats":{"total_commits":273,"total_committers":15,"mean_commits":18.2,"dds":0.63003663003663,"last_synced_commit":"035c5e18d6b23e8f25db378e9d2c6623bca38d0b"},"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/cljoly/rusqlite_migration","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cljoly%2Frusqlite_migration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cljoly%2Frusqlite_migration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cljoly%2Frusqlite_migration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cljoly%2Frusqlite_migration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cljoly","download_url":"https://codeload.github.com/cljoly/rusqlite_migration/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cljoly%2Frusqlite_migration/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31292639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","library","rusqlite","rust","schema","sqlite3"],"created_at":"2024-10-23T11:19:12.096Z","updated_at":"2026-04-01T22:20:19.488Z","avatar_url":"https://github.com/cljoly.png","language":"Rust","funding_links":["https://cj.rs/donate/"],"categories":[],"sub_categories":[],"readme":"\u003c!-- insert\n---\ntitle: \"Rusqlite Migration\"\ndate: 2021-08-21T15:32:05\ndescription: \"↕️ Simple database schema migration library for rusqlite, written with performance in mind.\"\naliases:\n- /rusqlite-migration\ntags:\n- Rust\n- SQLite\n- Library\n---\nend_insert --\u003e\n\n\u003c!-- remove --\u003e\n\u003cdiv align=\"center\"\u003e\n\n# Rusqlite Migration\n\u003c!-- end_remove --\u003e\n\n\u003c!-- rustdoc start --\u003e\n\n\u003c!-- insert\n{{\u003c github_badge \u003e}}\n\n{{\u003c rawhtml \u003e}}\n\u003cdiv class=\"badges\"\u003e\n{{\u003c /rawhtml \u003e}}\nend_insert --\u003e\n\n[![docs.rs](https://img.shields.io/docsrs/rusqlite_migration)][docs]\n[![Crates.io](https://img.shields.io/crates/v/rusqlite_migration)][cio]\n[![Changelog](https://img.shields.io/badge/-Changelog-purple)][changelog]\n[![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)][safety-dance]\n[![Coveralls](https://img.shields.io/coverallsCoverage/github/cljoly/rusqlite_migration)][coveralls]\n\n\u003c!-- insert\n{{\u003c rawhtml \u003e}}\nend_insert --\u003e\n\u003c/div\u003e\n\u003c!-- insert\n{{\u003c /rawhtml \u003e}}\nend_insert --\u003e\n\nRusqlite Migration is a performant and simple schema migration library for [rusqlite](https://crates.io/crates/rusqlite).\n\n* **Performance**:\n    * *Fast database opening*: to keep track of the current migration state, most tools create one or more tables in the database. These tables require parsing by SQLite and are queried with SQL statements. This library uses the [`user_version`][uv] value instead. It’s much lighter as it is just an integer at a [fixed offset][uv_offset] in the SQLite file.\n    * *Fast compilation*: this crate is very small and does not use macros to define the migrations.\n* **Simplicity**: this crate strives for simplicity. Just define a set of SQL statements as strings in your Rust code. Add more SQL statements over time as needed. No external CLI required. Additionally, rusqlite_migration works especially well with other small libraries complementing rusqlite, like [serde_rusqlite][].\n\n## Example\n\nHere, we define SQL statements to run with [`Migrations::new()`][migrations_new] and run these (if necessary) with [`Migrations::to_latest()`][migrations_to_latest].\n\n[migrations_new]: https://docs.rs/rusqlite_migration/latest/rusqlite_migration/struct.Migrations.html#method.new\n[migrations_to_latest]: https://docs.rs/rusqlite_migration/latest/rusqlite_migration/struct.Migrations.html#method.to_latest\n\n``` rust\nuse rusqlite::{params, Connection};\nuse rusqlite_migration::{Migrations, M};\n\n// 1️⃣ Define migrations\nconst MIGRATIONS_SLICE: \u0026[M\u003c'_\u003e] = \u0026[\n    M::up(\"CREATE TABLE friend(name TEXT NOT NULL);\"),\n    // In the future, add more migrations here:\n    //M::up(\"ALTER TABLE friend ADD COLUMN email TEXT;\"),\n];\nconst MIGRATIONS: Migrations\u003c'_\u003e = Migrations::from_slice(MIGRATIONS_SLICE);\n\nfn main() {\n    let mut conn = Connection::open_in_memory().unwrap();\n\n    // Apply some PRAGMA, often better to do it outside of migrations\n    conn.pragma_update_and_check(None, \"journal_mode\", \u0026\"WAL\", |_| Ok(()))\n        .unwrap();\n\n    // 2️⃣ Update the database schema, atomically\n    MIGRATIONS.to_latest(\u0026mut conn).unwrap();\n\n    // 3️⃣ Use the database 🥳\n    conn.execute(\"INSERT INTO friend (name) VALUES (?1)\", params![\"John\"])\n        .unwrap();\n}\n```\n\nPlease see the [examples](https://github.com/cljoly/rusqlite_migrate/tree/master/examples) folder for more, in particular:\n- migrations with multiple SQL statements (using for instance `r#\"…\"` or `include_str!(…)`)\n- migrations defined [from a directory][from_dir] with SQL files\n- migrations to [previous versions (downward migrations)][generic_example]\n- migrations [when using `async`][quick_start_async]\n\nI’ve also made a [cheatsheet of SQLite pragma for improved performance and consistency][cheat].\n\n### Built-in tests\n\nTo test that the migrations are working, you can add this in your test module:\n\n``` rust\n#[test]\nfn migrations_test() {\n    assert!(MIGRATIONS.validate().is_ok());\n}\n```\n\nThe migrations object is also suitable for serialisation with [insta][], using the `Debug` serialisation. You can store a snapshot of your migrations like this:\n\n```rust\n#[test]\nfn migrations_insta_snapshot() {\n    let migrations = Migrations::new(vec![\n        // ...\n    ]);\n    insta::assert_debug_snapshot!(migrations);\n}\n```\n\n[insta]: https://insta.rs/\n\n## Optional Features\n\nRusqlite migration provides several [Cargo features][cargo_features]. They are:\n\n* `from-directory`: enable loading migrations from *.sql files in a given directory\n\n[cargo_features]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section\n\n## Active Users\n\n\u003c!-- insert\n{{\u003c rawhtml \u003e}}\n\u003cdiv class=\"badges\"\u003e\n{{\u003c /rawhtml \u003e}}\nend_insert --\u003e\n\n[![Crates.io Downloads](https://img.shields.io/crates/d/rusqlite_migration?style=social)][cio] [![Crates.io Downloads (recent)](https://img.shields.io/crates/dr/rusqlite_migration?style=social)][cio]\n\n\u003c!-- insert\n{{\u003c rawhtml \u003e}}\n\u003c/div\u003e\n{{\u003c /rawhtml \u003e}}\nend_insert --\u003e\n\nThis crate is actively used in a number of projects. You can find up-to-date list of those on:\n\n* [crates.io][cio_reverse] / [lib.rs][lrs_reverse]\n* [GitHub’s list of dependent repositories][gh_reverse]\n\nA number of contributors are also reporting issues as they arise, another indicator of active use.\n\n## Minimum Supported Rust Version (MSRV)\n\nThis crate extends rusqlite and as such is tightly integrated with it. Thus, it supports the [same MSRV][msrv] as rusqlite. At the time of writing, this means:\n\n\u003e Latest stable Rust version at the time of release. It might compile with older versions.\n\n## Limits\n\n1. Since this crate uses the [`user_version`][uv_offset] field, if your program or any other library changes it, this library will behave in an unspecified way: it may return an error, apply the wrong set of migrations, do nothing at all...\n\n1. The [`user_version`][uv_offset] field is effectively a i32, so there is a theoretical limit (about two billion) on the number of migrations that can be applied by this library. You are likely to hit memory limits well before that though, so in practice, you can think of the number of migrations as limitless. And you would need to create 10 000 new migrations, every day, for over 5 centuries, before getting close to the limit.\n\n## Contributing\n\nContributions (documentation or code improvements in particular) are welcome, see [contributing][]!\n\nWe use various tools for testing that you may find helpful to install locally (e.g. to fix failing CI checks):\n* [cargo-insta][]\n* [cargo-mutants][]\n\n## Acknowledgments\n\nI would like to thank all the contributors, as well as the authors of the dependencies this crate uses.\n\nThanks to [Migadu](https://www.migadu.com/) for offering a discounted service to support this project. It is not an endorsement by Migadu though.\n\n[deps]: https://deps.rs/crate/rusqlite_migration\n[changelog]: https://cj.rs/rusqlite_migration/changelog\n[coveralls]: https://coveralls.io/github/cljoly/rusqlite_migration\n[safety-dance]: https://github.com/rust-secure-code/safety-dance/\n[cio]: https://crates.io/crates/rusqlite_migration\n[cio_reverse]: https://crates.io/crates/rusqlite_migration/reverse_dependencies\n[lrs_reverse]: https://lib.rs/crates/rusqlite_migration/rev\n[gh_reverse]: https://github.com/cljoly/rusqlite_migration/network/dependents?dependent_type=REPOSITORY\n[contributing]: https://cj.rs/docs/contribute/\n[diesel_migrations]: https://crates.io/crates/diesel_migrations\n[pgfine]: https://crates.io/crates/pgfine\n[movine]: https://crates.io/crates/movine\n[uv]: https://sqlite.org/pragma.html#pragma_user_version\n[uv_offset]: https://www.sqlite.org/fileformat.html#user_version_number\n[serde_rusqlite]: https://crates.io/crates/serde_rusqlite\n[cargo-insta]: https://crates.io/crates/cargo-insta\n[cargo-mutants]: https://mutants.rs/installation.html\n[cheat]: https://cj.rs/blog/sqlite-pragma-cheatsheet-for-performance-and-consistency/\n[docs]: https://docs.rs/rusqlite_migration\n[msrv]: https://github.com/rusqlite/rusqlite?tab=readme-ov-file#minimum-supported-rust-version-msrv\n[from_dir]: https://github.com/cljoly/rusqlite_migration/tree/master/examples/from-directory\n[generic_example]: https://github.com/cljoly/rusqlite_migration/blob/master/examples/simple/src/main.rs\n[quick_start_async]: https://github.com/cljoly/rusqlite_migration/blob/master/examples/async/src/main.rs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcljoly%2Frusqlite_migration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcljoly%2Frusqlite_migration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcljoly%2Frusqlite_migration/lists"}