Migrations
Database migrations are a way of versioning your database. Each migration is stored as an .sql file in your migrations folder. The migrations folder is created in your project directory when you create your first migration. This enables you to store and track changes throughout database development.
Currently, the migrations system aims to be simple yet effective. With the current implementation, you can:
Every migration file in the migrations folder has a specified version number in the filename. Files are listed in sequential order. Every migration file is an SQL file where you can specify queries to be run.
By default, migrations are created in the migrations/ folder in your Worker project directory. Creating migrations will keep a record of applied migrations in the d1_migrations table found in your database.
This location and table name can be customized in your Wrangler file, inside the D1 binding.
{ "d1_databases": [ { "binding": "<BINDING_NAME>", // i.e. if you set this to "DB", it will be available in your Worker at `env.DB` "database_name": "<DATABASE_NAME>", "database_id": "<UUID>", "preview_database_id": "<UUID>", "migrations_table": "<d1_migrations>", // Customize this value to change your applied migrations table name "migrations_dir": "<FOLDER_NAME>", // Specify your custom migration directory "migrations_pattern": "<GLOB>" // Optional: discover migrations using a glob pattern (see below) } ]}[[d1_databases]]binding = "<BINDING_NAME>"database_name = "<DATABASE_NAME>"database_id = "<UUID>"preview_database_id = "<UUID>"migrations_table = "<d1_migrations>"migrations_dir = "<FOLDER_NAME>"migrations_pattern = "<GLOB>"By default, wrangler d1 migrations apply looks for top-level .sql files inside migrations_dir. If you use an ORM such as Drizzle ↗ that writes each migration as its own subdirectory (for example, migrations/0001_init/migration.sql), set migrations_pattern to the glob that matches your layout:
{ "d1_databases": [ { "binding": "DB", "database_name": "my-database", "database_id": "<UUID>", "migrations_dir": "migrations", "migrations_pattern": "migrations/*/migration.sql" } ]}[[d1_databases]]binding = "DB"database_name = "my-database"database_id = "<UUID>"migrations_dir = "migrations"migrations_pattern = "migrations/*/migration.sql"Rules for migrations_pattern:
- When set,
migrations_dirmust also be set. - The pattern must start with whatever
migrations_diris set to. - Each migration's name is recorded in the migrations table as the path relative to
migrations_dir(for example,0001_init/migration.sql). This keeps the table portable across machines.
The pattern is a standard glob — * matches one path segment, ** matches any number of segments. migrations/**/*.sql will pick up arbitrarily deep .sql files.
wrangler d1 migrations create only writes top-level files inside migrations_dir, so if your migrations_pattern only matches nested files (as with the Drizzle layout), generate new migrations using your ORM's command (for example, drizzle-kit generate) instead.
When applying a migration, you may need to temporarily disable foreign key constraints. To do so, call PRAGMA defer_foreign_keys = true before making changes that would violate foreign keys.
Refer to the foreign key documentation to learn more about how to work with foreign keys and D1.