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

设置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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 23:35:32