| name | drizzle-v0 |
| description | Drizzle ORM v0.45+ reference for PostgreSQL. Auto-loads when working with drizzle-orm, pgTable, schema definitions, drizzle queries, migrations, drizzle-kit.
|
| user-invocable | false |
Drizzle ORM Reference
Version: 0.45.x
Docs: https://orm.drizzle.team/
See reference.md for the full API (imports, schema definition, queries, joins, transactions, raw SQL, relations, migrations).
Key Gotchas
Null vs Undefined in Updates
undefined fields are ignored, null fields are set to NULL:
await db.update(users).set({ name: undefined, age: 25 });
await db.update(users).set({ name: null, age: 25 });
Serial vs Identity Columns
PostgreSQL recommends identity columns over serial:
id: serial('id').primaryKey()
id: integer('id').primaryKey().generatedAlwaysAsIdentity()
Case Sensitivity
TypeScript keys map to DB columns as-is by default:
export const users = pgTable('users', {
firstName: varchar('first_name'),
});
const db = drizzle(pool, { casing: 'snake_case' });
Array Columns Require Default
Array columns need .default([]) or .notNull() will cause insert errors:
tags: text('tags').array().notNull().default([])
Vector Operations Need Explicit Op
pgvector indexes require .op() syntax:
index('embedding_idx').using('hnsw', table.embedding.op('vector_cosine_ops'))
Anti-Patterns
Don't: Select * in production
const users = await db.select().from(users);
const users = await db.select({ id: users.id, name: users.name }).from(users);
Don't: N+1 queries
const users = await db.select().from(users);
for (const user of users) {
const posts = await db.select().from(posts).where(eq(posts.authorId, user.id));
}
const result = await db.select().from(users).leftJoin(posts, eq(users.id, posts.authorId));
const result = await db.query.users.findMany({ with: { posts: true } });
Don't: Ignore type inference
const users: any = await db.select().from(users);
type User = typeof users.$inferSelect;
Don't: Use raw JSON.parse for JSONB
const metadata = JSON.parse(row.metadataJson);
Resources