在Vitest中执行Drizzle ORM迁移时出现磁盘I/O权限错误
解决Vitest beforeAll中Drizzle SQLite迁移的disk I/O错误
问题场景
直接运行db:migrate脚本(调用migrateWrapper执行迁移)完全正常,但在Vitest的beforeAll钩子中执行相同迁移逻辑时,抛出SqliteError: disk I/O error,最终导致__drizzle_migrations表创建失败。
可能的解决方案
1. 检查测试环境的数据库路径与权限
- 确认测试代码中配置的SQLite数据库路径和迁移脚本一致,若使用测试独立数据库,要确保路径存在且有读写权限。比如迁移脚本用
./dev.db,测试里如果指定./test.db,需保证该文件所在目录能正常读写。 - 避免使用系统临时目录中无权限的路径,必要时手动创建测试数据库的存放目录。
2. 禁用Vitest的并发测试
SQLite采用文件级锁机制,Vitest默认的并发测试会导致多个进程同时访问数据库文件,触发I/O错误:
- 在
vitest.config.ts中添加singleThread: true配置:export default defineConfig({ test: { singleThread: true, }, }); - 或者给涉及数据库操作的测试文件添加
serial标记,强制串行执行:import { describe, it } from 'vitest'; describe('数据库相关测试', { serial: true }, () => { // 测试逻辑 });
3. 确保beforeAll中异步迁移正确等待
检查beforeAll钩子是否正确await迁移函数的完成,遗漏await会导致迁移未执行完毕就开始测试,引发文件访问冲突:
beforeAll(async () => { // 必须await异步迁移操作 await migrateWrapper(); });
4. 统一SQLite连接配置
对比迁移脚本和测试中的Drizzle连接配置,确保测试中的连接包含正确的文件模式,比如添加mode: 'rwc'(读写创建),避免因文件不存在导致的I/O错误:
import { drizzle } from 'drizzle-orm/sqlite-proxy'; import { Database } from 'sqlite3'; const db = drizzle(new Database('./test.db', { mode: 'rwc' }));
内容的提问来源于stack exchange,提问作者Nikos
相关产品推荐
相关产品推荐

