You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 21:06:04