Drizzle
Initialize Drizzle in your app
env.ts first.1. Install dependencies
2. .env.local
Create a .env.local file in the root of your project and add the following:
3. Add DATABASE_URL to env.ts if needed
4. Folder Structure
Tree View
Remember to replace <project-name> with the name of your project.
5. Start Database
6. Add your schema (Example)
7. Add scripts to package.json
8. Apply Migrations
Preflight for an existing production database
drizzle-kit migrate applies every journal entry with a timestamp newer than the last applied migration. Before running it against a database that already holds schema, check:
- Journal order: timestamps must ascend with
idx. A stalewhenon an old entry makes the migrator skip it forever and start at a later migration whose statements reference objects that do not exist. - Push-synced schema: if the database was ever updated with
drizzle-kit push, later migrations may fail withcolumn already existsor reference constraints that were created under different names. - Missing tables the code references: grep the schema exports and compare against
information_schema.tables. - Duplicate rows: any new
UNIQUEconstraint fails to add when duplicates exist for its columns. Check withGROUP BY ... HAVING count(*) > 1and dedupe first. - Orphan rows: re-created foreign keys with
ON DELETE CASCADEfail when child rows reference missing parents.
Inspect the divergence with catalog queries (pg_constraint, pg_indexes, information_schema.columns) rather than assuming the journal reflects the database. Apply repairs in a transaction with pre-checks, then register applied migrations in the migrations table with the same sha256 hash the migrator uses so future runs stay no-ops.
After any schema change, pnpm db:check must pass and a no-op pnpm db:migrate must succeed.