SQL scripts migration runner
Database migrations in plain SQL.
Keep your database changes alongside your application code. grate runs your SQL scripts in a predictable order and records what has been applied, so you can deploy the same changes from your laptop, your tests, or your CI/CD pipeline. Use your database's SQL dialect and features without a migration DSL or an ORM.
Supports SQL Server (including Azure SQL), PostgreSQL, MariaDB/MySQL, SQLite, and Oracle, on Windows, Linux, and macOS.
Documentation · Installation · Releases · Examples · Contributing
Schema changes and stored procedure definitions have different maintenance needs. grate lets you keep both in source control without turning every edit into a new one-time migration.
| Script type | Default folders include | When it runs |
|---|---|---|
| One-time | up |
Once per database. Changing an applied script fails the migration by default. |
| Anytime | functions, views, sprocs, indexes |
When the script is new or has changed. Write these scripts so they can run again. |
| Everytime | beforeMigration, permissions, afterMigration |
On every migration, whether the script has changed or not. |
Folders run in a defined order, with scripts sorted alphabetically within them. Create only the folders you need, or customize the layout and execution policies to fit an existing project. grate stores migration history in the target database, including script names, hashes, and versions.
This example uses a local database file, so you don't need a database server.
Install the .NET tool with the .NET SDK and a matching runtime installed:
dotnet tool install --global gratePrefer a standalone executable or Docker? See installation options and runtime requirements.
Create a directory named db/up and save this as db/up/001_create_greetings.sql:
CREATE TABLE greetings (
id INTEGER PRIMARY KEY,
message TEXT NOT NULL
);Run from the directory containing db:
grate --databasetype sqlite --connectionstring "Data Source=hello-grate.db" --files ./db --silentgrate creates hello-grate.db, runs the script, and records it in its migration
history. Run the same command again: the unchanged one-time script is skipped.
For the next schema change, add 002_...sql to db/up and run grate again.
For another database, select its --databasetype and supply its connection string.
See getting started for the full folder order and workflow.
Use the CLI locally and in CI/CD, run it in a container, or embed the .NET libraries in your application or test setup.
| What you want to do | Where to start |
|---|---|
| Configure connections, transactions, previews, or baselining | Configuration options |
| Select scripts by environment or supply deployment values | Environment scripts and token replacement |
| Run migrations in a pipeline | GitHub Actions, Azure Pipelines, and CI logging |
| Run migrations in containers or Kubernetes | Docker, init containers, and multi-tenant deployments |
| Prepare a database for automated tests | Test integration example |
| Work with a coding agent | Bundled use-grate skill |
grate grew out of experience maintaining RoundhousE and carries forward its SQL-first workflow. See migrating from RoundhousE for compatibility details and the changes to make when moving an existing project.
Bug reports, documentation improvements, and code contributions are welcome. Start with CONTRIBUTING.md for development setup and tests, or open an issue to report a problem or discuss an idea. Coding agents should also follow AGENTS.md.
We welcome AI-assisted contributions. You are responsible for understanding, reviewing, and verifying the changes you submit, with the same quality standards as code you wrote yourself. Include good automated test coverage for new behavior and regression tests for bug fixes, and describe the checks you ran and any gaps.
grate is short for migrate, pronounced like great, and MIT licensed.