
drizzle
PopülerDrizzle ORM schema and database guide. Use when working with database schemas (src/database/schemas/*), defining tables, creating migrations, or database model code. Triggers on Drizzle schema definition, database migrations, or ORM usage questions.
Drizzle ORM schema and database guide. Use when working with database schemas (src/database/schemas/*), defining tables, creating migrations, or database model code. Triggers on Drizzle schema definition, database migrations, or ORM usage questions.
Drizzle ORM Schema Style Guide
Configuration
- Config:
drizzle.config.ts - Schemas:
src/database/schemas/ - Migrations:
src/database/migrations/ - Dialect:
postgresqlwithstrict: true
Helper Functions
Location: src/database/schemas/_helpers.ts
timestamptz(name): Timestamp with timezonecreatedAt(),updatedAt(),accessedAt(): Standard timestamp columnstimestamps: Object with all three for easy spread
Naming Conventions
- Tables: Plural snake_case (
users,session_groups) - Columns: snake_case (
user_id,created_at)
Column Definitions
Primary Keys
id: text('id')
.primaryKey()
.$defaultFn(() => idGenerator('agents'))
.notNull(),
ID prefixes make entity types distinguishable. For internal tables, use uuid.
Foreign Keys
userId: text('user_id')
.references(() => users.id, { onDelete: 'cascade' })
.notNull(),
Timestamps
...timestamps, // Spread from _helpers.ts
Indexes
// Return array (object style deprecated)
(t) => [uniqueIndex('client_id_user_id_unique').on(t.clientId, t.userId)],
Type Inference
export const insertAgentSchema = createInsertSchema(agents);
export type NewAgent = typeof agents.$inferInsert;
export type AgentItem = typeof agents.$inferSelect;
Example Pattern
export const agents = pgTable(
'agents',
{
id: text('id').primaryKey().$defaultFn(() => idGenerator('agents')).notNull(),
slug: varchar('slug', { length: 100 }).$defaultFn(() => randomSlug(4)).unique(),
userId: text('user_id').references(() => users.id, { onDelete: 'cascade' }).notNull(),
clientId: text('client_id'),
chatConfig: jsonb('chat_config').$type<LobeAgentChatConfig>(),
...timestamps,
},
(t) => [uniqueIndex('client_id_user_id_unique').on(t.clientId, t.userId)],
);
Common Patterns
Junction Tables (Many-to-Many)
export const agentsKnowledgeBases = pgTable(
'agents_knowledge_bases',
{
agentId: text('agent_id').references(() => agents.id, { onDelete: 'cascade' }).notNull(),
knowledgeBaseId: text('knowledge_base_id').references(() => knowledgeBases.id, { onDelete: 'cascade' }).notNull(),
userId: text('user_id').references(() => users.id, { onDelete: 'cascade' }).notNull(),
enabled: boolean('enabled').default(true),
...timestamps,
},
(t) => [primaryKey({ columns: [t.agentId, t.knowledgeBaseId] })],
);
Database Migrations
See references/db-migrations.md for detailed migration guide.
# Generate migrations
bun run db:generate
# After modifying SQL (e.g., adding IF NOT EXISTS)
bun run db:generate:client
Migration Best Practices
-- ✅ Idempotent operations
ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "avatar" text;
DROP TABLE IF EXISTS "old_table";
CREATE INDEX IF NOT EXISTS "users_email_idx" ON "users" ("email");
-- ❌ Non-idempotent
ALTER TABLE "users" ADD COLUMN "avatar" text;
Rename migration files meaningfully: 0046_meaningless.sql → 0046_user_add_avatar.sql
You Might Also Like
Related Skills

verify
Use when you want to validate changes before committing, or when you need to check all React contribution requirements.
facebook
test
Use when you need to run tests for React core. Supports source, www, stable, and experimental channels.
facebook
feature-flags
Use when feature flag tests fail, flags need updating, understanding @gate pragmas, debugging channel-specific test failures, or adding new flags to React.
facebook
extract-errors
Use when adding new error messages to React, or seeing "unknown error code" warnings.
facebook