Drizzle ORM
This document describes how we use Drizzle ORM for database operations in the Registration Backend service with examples.
Overview
We use Drizzle ORM as our database layer. Drizzle provides type-safe database queries with minimal abstraction over SQL.
Database Setup
Local Development
Start PostgreSQL with Docker:
docker compose up -d
Copy the example environment file and configure it:
cp .env.example .env
Stage and Production
In production and stage, the database runs on AWS Aurora (PostgreSQL).
Schema Definition
Schemas are defined in TypeScript files under app/database/. See
app/database/schemas for example.
Database Connection
Get the database client using getDB() from
app/database/db.server.ts:
import { getDb } from "~/database/db.server.js";
const db = await getDb();
const users = await db.select().from(users);
Migrations
Generate Migration
After changing your schema, generate a migration:
pnpm run db:generate
This creates a SQL file in packages/migrations/drizzle/. Review the generated
SQL before applying.
Apply Migration
Apply pending migrations:
pnpm run db:migrate
Seed Database
Populate the database with example data for local development:
pnpm run db:seed
View Database
Open Drizzle Studio to browse your database:
pnpm run db:studio
Querying
See Drizzle docs for query examples.
Type Safety
Types are automatically inferred from schema definitions:
import type { InferSelectModel } from "drizzle-orm";
import { users } from "~/database/schemas/users";
type User = InferSelectModel<typeof usersTableExample>;