Migrations
Now that we have defined our schema in TypeScript, we need to tell our actual database about these tables. We do this using Migrations.
Think of migrations as “version control” for your database. They track changes over time (e.g., creating a table, adding a column).
Configuration
Section titled “Configuration”First, we need to configure Drizzle Kit. This tool looks at your schema file and generates the necessary SQL commands.
Create a drizzle.config.ts file in your project root:
import { defineConfig } from "drizzle-kit";
export default defineConfig({ out: "./drizzle", // Where to save migration files schema: "./src/worker/db/schema.ts", // Path to your schema dialect: "sqlite", driver: "d1-http",});You also need to make sure your wrangler.json is set up with a D1 database binding.
{ "d1_databases": [ { "binding": "DB", // How we access it in code (env.DB) "database_name": "my-app-db", "database_id": "xxxx-xxxx-xxxx-xxxx", // Your D1 ID "migrations_dir": "drizzle" // Must match 'out' in drizzle.config.ts } ]}The Workflow
Section titled “The Workflow”-
Generate Migrations
Run the generate command. Drizzle Kit will compare your TypeScript schema to the existing migration files and generate a new SQL file for any changes.
Terminal window bunx drizzle-kit generateYou will see a new file in your
drizzle/folder, something like0000_init.sql. -
Apply Migrations (Local)
To apply these changes to your local development database:
Terminal window bunx wrangler d1 migrations apply my-app-db --local -
Apply Migrations (Production)
To apply these changes to your live production database:
Terminal window bunx wrangler d1 migrations apply my-app-db --remote
Why this is powerful
Section titled “Why this is powerful”- Safety: You review the SQL before it runs.
- History: You have a record of every change made to your DB.
- Reproducibility: Anyone on your team can run the migrations and get the exact same database structure.
In the next section, we will write code to interact with this database!