Skip to content

迁移

IBest-ORM 提供智能的数据库迁移功能,自动同步模型定义与数据库表结构。

自动迁移

使用 migrate() 方法自动同步模型到数据库:

ts
import { getORM, Table, Column, PrimaryKey } from '@ibestservices/ibest-orm';

@Table()
class User {
  @PrimaryKey()
  id?: number;

  @Column()
  name?: string;

  @Column()
  age?: number;
}

const orm = getORM();

// 自动创建或更新表结构
orm.migrate(User);

// 同步多个模型
orm.migrate(User, Article, Order);

迁移操作

新增字段

当模型添加新字段时,migrate() 会自动添加对应的数据库列:

ts
@Table()
class User {
  @PrimaryKey()
  id?: number;

  @Column()
  name?: string;

  @Column()
  email?: string;  // 新增字段,migrate 会自动添加
}

orm.migrate(User);

删除字段

当模型移除字段时,migrate() 会删除对应的数据库列(带数据备份):

ts
@Table()
class User {
  @PrimaryKey()
  id?: number;

  @Column()
  name?: string;
  // email 字段已移除,migrate 会删除该列
}

orm.migrate(User);

修改字段类型

当字段类型变更时,migrate() 会自动修改列类型:

ts
@Table()
class User {
  @PrimaryKey()
  id?: number;

  @Column()
  age?: string;  // 从 number 改为 string
}

orm.migrate(User);

迁移日志

IBest-ORM 会记录每次迁移操作,可以查询迁移历史:

ts
// 获取迁移日志
const logs = orm.getMigrationLogs();

logs.forEach(log => {
  console.log(`表: ${log.tableName}`);
  console.log(`操作: ${log.operation}`);
  console.log(`时间: ${log.createdAt}`);
  console.log(`SQL: ${log.sql}`);
  console.log(`回滚SQL: ${log.rollbackSql}`);
});

回滚支持

每次迁移都会生成回滚 SQL,可用于手动回滚:

ts
// 获取最近的迁移日志
const logs = orm.getMigrationLogs();
const lastLog = logs[logs.length - 1];

if (lastLog && lastLog.rollbackSql) {
  console.log('回滚 SQL:', lastLog.rollbackSql);
  // 可以手动执行回滚 SQL
}

表操作

检查表是否存在

ts
// 使用实体类
const exists = orm.hasTable(User);

// 或使用表名
const exists2 = orm.hasTable('user');

// 验证迁移是否成功
orm.migrate(User);
if (orm.hasTable(User)) {
  console.log('User 表创建成功');
}

获取表信息

ts
const columns = orm.getTableInfo(User);
// 返回: [{ name: 'id', type: 'INTEGER', notnull: false, pk: true }, ...]

columns.forEach(col => {
  console.log(`列名: ${col.name}, 类型: ${col.type}, 非空: ${col.notnull}, 主键: ${col.pk}`);
});

检查列是否存在

ts
// 使用实体类
const hasName = orm.hasColumn(User, 'name');

// 或使用表名
const hasEmail = orm.hasColumn('user', 'email');

// 验证字段迁移
orm.migrate(User);
if (orm.hasColumn(User, 'email')) {
  console.log('email 字段已添加');
}

最佳实践

  1. 开发环境:可以频繁使用 migrate() 同步模型变更
  2. 生产环境:建议在应用启动时执行一次 migrate()
  3. 数据备份:重要数据变更前建议先备份
  4. 查看日志:通过迁移日志了解数据库变更历史
ts
// 应用初始化时同步所有模型
import { IBestORMInit, getORM } from '@ibestservices/ibest-orm';

// 初始化
await IBestORMInit(context, { name: 'app.db' });
const orm = getORM();

// 同步所有模型
orm.migrate(User, Article, Order, Comment);

// 验证迁移结果
console.log('User 表存在:', orm.hasTable(User));
console.log('User 表结构:', orm.getTableInfo(User));

注意事项

  1. SQLite 限制:SQLite 不支持 ALTER COLUMN,修改列类型时会重建表
  2. 数据安全:删除列时数据会丢失,请确保已备份
  3. 索引处理:目前迁移不会自动处理索引变更