- typeorm 可以通过 ts 定义表结构来同步生成表结构,但是如果表里已存在记录,则新增加的字段要设置为可空,不然老记录是没有这个字段值的,更新不了表结构。
- 在开发时,更新表结构最好清空所有数据。
- 可以手动运行
yarn run typeorm schema:sync
来同步表结构。 - 最好的方式是生成迁移文件,然后修改迁移文件来执行同步。
以下命令创建一个空的迁移文件,然后需要修改
typeorm migration:create -n NAME
也可以是先修改模型,然后
typeorm migration:generate -n NAME
这样会生成一个基本的变动 sql 命令。还需要修改才能完美迁移。
运行 yarn run typeorm schema:sync
相当于不生成迁移文件直接修改表结构,如果新增字段不为空,多半是失败的。
下面修改了迁移 sql 语句,原表不存在的字段需要用 ''
代替。
import {MigrationInterface, QueryRunner} from "typeorm";
export class test1231683344643352 implements MigrationInterface {
name = 'test1231683344643352'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TABLE "temporary_alert" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "created_at" datetime NOT NULL, "code" varchar(20) NOT NULL, "name" varchar(100) NOT NULL, "condition" varchar(100) NOT NULL)`);
// 修改这句,模型新增字段为 condition, 需要修改语句为 "" AS condition
await queryRunner.query(`INSERT INTO "temporary_alert"("id", "created_at", "code", "name", "condition") SELECT "id", "created_at", "code", "name", "" AS condition FROM "alert"`);
await queryRunner.query(`DROP TABLE "alert"`);
await queryRunner.query(`ALTER TABLE "temporary_alert" RENAME TO "alert"`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "alert" RENAME TO "temporary_alert"`);
await queryRunner.query(`CREATE TABLE "alert" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "created_at" datetime NOT NULL, "code" varchar(20) NOT NULL, "name" varchar(100) NOT NULL)`);
await queryRunner.query(`INSERT INTO "alert"("id", "created_at", "code", "name") SELECT "id", "created_at", "code", "name" FROM "temporary_alert"`);
await queryRunner.query(`DROP TABLE "temporary_alert"`);
}
}
然后运行迁移 yarn run typeorm migration:run
。