设置migrationsRun: true后TypeORM迁移无法执行的问题排查
React Native + Expo + TypeORM SQLite迁移不生效问题排查与解决
我搭建了基于React Native + Expo的项目,使用SQLite数据库与TypeORM。尝试将数据源配置中的migrationsRun设为true,在应用启动时执行迁移为已有的Note表添加isPrivate列,但操作未生效,TypeORM完全无法识别迁移(路径配置确认正确)。当Note实体中定义isPrivate列并调用repository的find方法时,抛出错误:
no such column: Note.isPrivate (code 1 SQLITE_ERROR): , while compiling: SELECT "Note"."id" AS "Note_id", "Note"."title" AS "Note_title", "Note"."details" AS "Note_details", "Note"."isPrivate" AS "Note_isPrivate", "Note"."folderId" AS "Note_folderId" FROM "note" "Note"
相关代码
data-source.ts
import "reflect-metadata"; import { DataSource } from "typeorm"; import * as sqlitedriver from 'expo-sqlite'; import Folder from './entities/Folder.model.ts'; import Note from './entities/Note.model.ts'; const AppDataSource = new DataSource({ driver: sqlitedriver, database: 'app_db', type: 'expo', migrationsRun: true, entities: [Folder, Note], migrations: ['migrations/*.ts'], }); AppDataSource.initialize().then(() => { console.log("Data Source has been initialized!"); }).catch((err) => { console.error("Error during Data Source initialization", err.message); }); export default AppDataSource;
迁移文件(AddIsPrivateColumn1684782594104.ts)
import { MigrationInterface, QueryRunner } from "typeorm"; import { TableColumn } from "typeorm"; export class AddIsPrivateColumn1684782594104 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise<void> { await queryRunner.addColumn( "Note", new TableColumn({ name: "isPrivate", type: "boolean", }), ); }; public async down(queryRunner: QueryRunner): Promise<void> { await queryRunner.dropColumn("Note", "isPrivate"); }; };
解决步骤
1. 修正迁移路径配置
Expo环境下TypeORM对相对路径的解析可能存在问题,改用绝对路径确保能找到迁移文件:
// 先导入path模块 import * as path from 'path'; // 修改migrations配置 migrations: [path.join(__dirname, './migrations/*.ts')],
2. 统一表名大小写
SQLite表名实际为小写note,迁移中使用大写Note会导致找不到表,修正迁移文件中的表名:
public async up(queryRunner: QueryRunner): Promise<void> { await queryRunner.addColumn( "note", // 改为小写表名 new TableColumn({ name: "isPrivate", type: "boolean", default: false, // 建议添加默认值,避免现有数据出现NULL nullable: false, // 可选:设置为非空 }), ); };
3. 手动触发迁移执行
即使设置了migrationsRun: true,仍可在数据源初始化后手动调用迁移执行,确保迁移被触发:
AppDataSource.initialize().then(async () => { console.log("Data Source has been initialized!"); // 手动执行迁移 await AppDataSource.runMigrations(); }).catch((err) => { console.error("Error during Data Source initialization", err.message); });
4. 检查迁移记录表
TypeORM会自动创建migrations表记录已执行的迁移,若该表不存在,说明迁移从未被执行过。可以卸载应用后重新安装,清除旧数据库,再测试迁移是否正常执行。
5. 确认依赖版本兼容性
确保使用的TypeORM版本与Expo SQLite驱动兼容,推荐使用TypeORM 0.3.x版本,对应@typeorm/expo-sqlite驱动(若使用旧版本,需确认expo-sqlite驱动是否适配)。
内容的提问来源于stack exchange,提问作者3ternal
相关产品推荐
相关产品推荐

