Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/content/docs/d1/reference/community-projects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ Drizzle is a headless TypeScript ORM with a head which runs on Node, Bun and Den
* [GitHub](https://github.com/drizzle-team/drizzle-orm)
* [D1 example](https://orm.drizzle.team/docs/connect-cloudflare-d1)

:::caution[Using Drizzle migrations with D1]

When using Drizzle with D1, be aware of the following:

- **`drizzle-kit migrate` does not work with D1.** Drizzle cannot apply migrations to D1 directly because D1 requires Cloudflare's API for writes. Use `drizzle-kit generate` to create the SQL migration files, then apply them with `wrangler d1 migrations apply`. Refer to [Nested migration layouts](/d1/reference/migrations/#nested-migration-layouts) for how to configure `wrangler` to read Drizzle's output folder.
- **`drizzle-kit generate` will try to drop tables not in your schema file.** Drizzle assumes it owns every table in the database. Tables that exist in the database but are not defined in your TypeScript schema — including the `d1_migrations` tracking table and Cloudflare's internal `_cf_KV` table — will appear as `DROP TABLE` statements in generated migrations. Always review generated SQL before applying. To prevent this, add `tablesFilter` to your `drizzle.config.ts`: `["!d1_migrations", "!_cf_KV", "!sqlite_sequence"]`. If you customized the tracking table name via `migrations_table` in your Wrangler configuration, use that name instead of `d1_migrations`.
- **Drizzle and `wrangler` track migrations separately.** `wrangler` records applied migrations in the `d1_migrations` table. Drizzle tracks them in `drizzle/meta/_journal.json`. These two systems do not communicate. If you use both, let `wrangler` handle tracking and use Drizzle only for SQL generation.

:::

### workers-qb

`workers-qb` is a zero-dependency query builder that provides a simple standardized interface while keeping the benefits and speed of using raw queries over a traditional ORM. While not intended to provide ORM-like functionality, `workers-qb` makes it easier to interact with your database from code for direct SQL access.
Expand Down
28 changes: 28 additions & 0 deletions src/content/docs/d1/reference/migrations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,34 @@ The pattern is a standard glob — `*` matches one path segment, `**` matches an

`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.

## Generate migrations with an ORM

You can use an object-relational mapping (ORM) tool like [Drizzle](https://orm.drizzle.team/) or [Prisma](https://www.prisma.io/) to generate migration SQL instead of writing it by hand. With an ORM, you define your schema in TypeScript (or a schema file), and the ORM's CLI detects changes and outputs `.sql` migration files.

ORMs cannot apply migrations to D1 directly. D1 requires Cloudflare's API for writes, so you must use `wrangler` to apply the generated SQL. The workflow is:

1. Define or edit your schema in TypeScript (or your ORM's schema format).
2. Run your ORM's migration generation command (for example, `drizzle-kit generate`) to produce a `.sql` file.
3. Review the generated SQL for destructive statements. ORMs may generate `DROP TABLE` statements for tables they do not manage, such as the `d1_migrations` tracking table.
4. Apply the migration with `wrangler d1 migrations apply`.

To connect an ORM's migration output folder to `wrangler`, use `migrations_dir` and `migrations_pattern` in your [Wrangler configuration](#wrangler-customizations). Refer to [Nested migration layouts](#nested-migration-layouts) for an example using Drizzle's subdirectory layout.

### ORM vs. raw SQL

Raw SQL migrations with `wrangler` work well when you have a small number of tables, your queries are basic, you are comfortable writing SQL, or you are the only developer on the project.

An ORM starts to pay off in the following situations:

- Your schema grows to many tables with foreign key relationships.
- You build complex queries with joins across multiple tables and want compile-time type safety.
- Multiple developers touch the schema and need a single TypeScript definition as the source of truth.
- You want editor autocompletion when writing queries.

Either way, always review migration SQL before applying to production.

For a list of ORMs, query builders, and tools that work with D1, refer to [Community projects](/d1/reference/community-projects/).

## Foreign key constraints

When applying a migration, you may need to temporarily disable [foreign key constraints](/d1/sql-api/foreign-keys/). To do so, call `PRAGMA defer_foreign_keys = true` before making changes that would violate foreign keys.
Expand Down