用途
drizzle-migrations 是一个帮助开发者使用 Drizzle ORM 管理数据库模式变更的技能,目标数据库为 SQLite。根据资料,它适用于:新增表或修改已有列、生成并运行数据库迁移、Drizzle 特有的查询模式与关系、Drizzle 下的 SQLite 模式最佳实践,以及 Drizzle 配置的搭建。
资料同时明确了不适用(DO NOT use)的情况:Supabase/PostgreSQL 请使用 supabase-admin 技能;不涉及 Drizzle 的原生 SQL 请使用标准 SQL 资源;Prisma ORM 的语法与模式不同;通用的数据库设计理论请使用数据库架构相关资源。
项目配置
配置文件为 drizzle.config.ts,示例内容为:从 drizzle-kit 导入 defineConfig,导出配置对象,包含字段 schema: './src/db/schema.ts'、out: './drizzle'、dialect: 'sqlite'、dbCredentials: { url: './data/app.db' }。
命令(资料给出的 npm 脚本):
- npm run db:generate:生成迁移文件
- npm run db:push:直接推送 schema(仅限开发环境)
- npm run db:studio:打开 Drizzle Studio 图形界面
模式定义文件位置为 src/db/schema.ts,表单定义与关系定义均从该文件导出。
主要能力
模式定义
资料展示了基础表、带外键的表以及带复合索引的表三种定义方式。基础表 users 使用 sqliteTable 定义,字段包括:id(text 主键)、email(text,notNull,unique)、username(text,notNull)、passwordHash(text)、createdAt(text,notNull,默认 sqlCURRENT_TIMESTAMP)、updatedAt(text)。
带外键的表 checkIns 中,userId 使用 references(() => users.id, { onDelete: 'cascade' }),其余字段包括 mood(integer,notNull)、cravingLevel(integer,notNull)、sleepHours(real)、notes(text)、createdAt。
带复合索引的表 auditLog 中,通过回调返回索引对象:userActionIdx 为 index('idx_audit_user_action').on(table.userId, table.action),createdAtIdx 为 index('idx_audit_created').on(table.createdAt)。
关系(Relations)通过 drizzle-orm 的 relations 定义,示例中 usersRelations 使用 many 声明 checkIns、sessions、journalEntries 的一对多关系;checkInsRelations 使用 one 声明 user 关系,fields 与 references 分别指向 checkIns.userId 和 users.id。
列类型
资料列出了 Drizzle 中 SQLite 的类型映射:text 对应 TEXT(字符串、JSON、日期);integer 对应 INTEGER(数字、布尔值以 0/1 存储);real 对应 REAL(浮点数);blob 对应 BLOB(二进制数据)。示例还展示了几种用法:布尔值使用 integer('is_active', { mode: 'boolean' }).default(true);JSON 使用 text('metadata', { mode: 'json' });枚举使用 text('status', { enum: ['pending', 'active', 'archived'] });日期以 ISO 字符串存储,createdAt 默认 sqlCURRENT_TIMESTAMP。
迁移策略
资料给出两种策略:
策略一:Push(仅开发环境)。执行 npm run db:push,直接应用 schema 变更,速度快,适合开发;资料明确强调绝不要用于生产环境。
策略二:Generate & Migrate(生产)。步骤为:先执行 npm run db:generate 生成迁移文件;再检查 /drizzle 文件夹中生成的 SQL;最后在代码中或手动应用迁移。
在代码中应用迁移的示例:从 drizzle-orm/better-sqlite3 导入 drizzle,从 drizzle-orm/better-sqlite3/migrator 导入 migrate,从 better-sqlite3 导入 Database;创建 sqlite 实例、db 实例后,调用 migrate(db, { migrationsFolder: './drizzle' })。
常见模式变更
新增表:在 schema.ts 中添加表定义与关系,然后运行 db:generate 生成迁移。
新增列:在 schema.ts 对应表中添加新列,然后生成迁移。
新增索引:在表定义回调中追加 index(...).on(...) 定义,然后生成迁移。
重命名(需要手写 SQL):资料指出旧版本 SQLite 不直接支持列重命名。复杂变更的手动迁移步骤为:先创建新表 users_new(其中 display_name 由 username 重命名而来);再用 INSERT INTO users_new SELECT ... FROM users 复制数据;接着 DROP TABLE users;最后 ALTER TABLE users_new RENAME TO users。
查询模式
资料覆盖了以下查询能力,均给出代码示例:
基础查询:select().from(users);带条件查询 where(eq(users.isActive, true));选择特定列(传入列对象);复杂 where 子句使用 and、gte、lte 组合并配合 orderBy(desc(...)) 与 limit(30)。相关操作符从 drizzle-orm 导入,包括 eq、and、or、desc、asc、like、gte、lte。
插入:单条插入配合 .returning();批量插入传入数组;Upsert 使用 onConflictDoUpdate({ target: users.id, set: { email: 'new@example.com' } })。
更新:update(users).set(...).where(...),示例中同时更新 username 与 updatedAt(new Date().toISOString())。
删除:delete(...).where(...);多条件删除使用 and 组合,资料特别提醒始终使用 WHERE 子句。
联表:leftJoin(checkIns, eq(users.id, checkIns.userId)),并选择 user 与 checkIn 两个对象。
聚合:从 drizzle-orm 导入 count、avg、sum、max、min,示例统计 totalCheckIns、avgMood、maxStreak。
最佳实践
资料列出的最佳实践包括:对相关变更始终使用事务(db.transaction(async (tx) => { ... }));DELETE/UPDATE 始终带 WHERE;为高频查询列建立索引;SQLite 中日期以 ISO 字符串存储;使用 returning() 获取插入或更新的行;生成迁移而非在生产环境使用 push。
使用方式
按资料所述,典型流程为:配置 drizzle.config.ts → 在 src/db/schema.ts 中定义表与关系 → 开发阶段可用 npm run db:push 快速应用 → 生产阶段用 npm run db:generate 生成迁移、检查生成的 SQL、再通过 migrator 在代码中运行迁移;查询时从 schema 导入表并使用 drizzle-orm 的操作符与聚合函数。
适用场景与限制
适用场景为使用 Drizzle ORM 搭配 SQLite 的项目进行模式演进与数据访问。限制与边界包括:不适用于 Supabase/PostgreSQL、非 Drizzle 的原生 SQL、Prisma ORM 以及通用数据库设计理论;db:push 仅限开发、绝不可用于生产;SQLite 旧版本不直接支持列重命名,需手写 SQL 迁移并按建新表、复制数据、删旧表、重命名的步骤执行。
参考
资料给出的参考为 Drizzle ORM Docs、Drizzle SQLite、Drizzle Migrations。