NodeJS 无法通过type-orm迁移删除列

but5z9lq  于 2023-04-05  发布在  Node.js
关注(0)|答案(1)|浏览(162)

我有一个测试实体,它的creatorId字段最初的类型是integer,在将其更改为string并运行迁移后,它的类型仍然是int,所以我完全删除了该字段,并添加了另一个字段userId并运行迁移,这次它添加了userId列,但没有删除creatorId列。

测试实体:

@ObjectType()
@Entity()
export class Test extends BaseEntity {
  @Field()
  @PrimaryGeneratedColumn()
  id!: number;

  @Field(() => String)
  @Column()
  creatorId: string; // problem here

  @ManyToOne(() => User, (user) => user.tests)
  creator: User;

  @Field()
  @Column()
  time: string;

  @Field()
  @Column()
  accuracy: string;

  @Field()
  @Column()
  wpm: number;

  @Field()
  @Column()
  chars: string;

  @Field(() => String)
  @CreateDateColumn()
  createdAt: Date;
}

脚本

"scripts": {
    "watch": "tsc -w",
    "dev": "nodemon dist/index.js",
    "start": "node dist/index.js",
    "typeorm": "ts-node ./node_modules/typeorm/cli",
    "migration:create": "typeorm migration:create ./src/migrations/migration",
    "migration:run": "ts-node ./node_modules/typeorm/cli --dataSource ./dist/data-source.js migration:run",
    "migration:generate": "ts-node ./node_modules/typeorm/cli --dataSource ./dist/data-source.js migration:generate ./src/migrations/migration",
    "migration:show": "ts-node ./node_modules/typeorm/cli --dataSource ./dist/data-source.js migration:show"
  },

数据源.ts

import { DataSource } from 'typeorm';
import dotenv from 'dotenv';
import { User } from './entities/user';
import { Test } from './entities/test';

dotenv.config();

export const AppDataSource = new DataSource({
  type: 'postgres',
  host: 'localhost',
  port: 5432,
  database: 'type-io',
  username: process.env.DATABASE_USERNAME?.toString(),
  password: process.env.DATABASE_PASSWORD?.toString(),
  logging: true,
  synchronize: false,
  entities: [Test, User],
  migrations: [],
  cache: false,
});

AppDataSource.initialize()
  .then(async () => {
    console.log('Data Source has been initialized!');
  })
  .catch((err) => {
    console.error('Error during Data Source initialization', err);
  });

另外,迁移字段为空的原因是,只有当我从迁移文件导入迁移类时,它才能工作,引用路径不起作用
下面是一个例子,当我将userId字段重命名为creatorId时,生成的查询如下:

import { MigrationInterface, QueryRunner } from "typeorm";

export class migration1680420345316 implements MigrationInterface {
    name = 'migration1680420345316'

    public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`ALTER TABLE "test" DROP COLUMN "userId"`);
        await queryRunner.query(`ALTER TABLE "test" DROP CONSTRAINT "FK_ab6d476e7698322a3a35b5fdb12"`);
        await queryRunner.query(`ALTER TABLE "test" ALTER COLUMN "creatorId" SET NOT NULL`);
        await queryRunner.query(`ALTER TABLE "test" ADD CONSTRAINT "FK_ab6d476e7698322a3a35b5fdb12" FOREIGN KEY ("creatorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`ALTER TABLE "test" DROP CONSTRAINT "FK_ab6d476e7698322a3a35b5fdb12"`);
        await queryRunner.query(`ALTER TABLE "test" ALTER COLUMN "creatorId" DROP NOT NULL`);
        await queryRunner.query(`ALTER TABLE "test" ADD CONSTRAINT "FK_ab6d476e7698322a3a35b5fdb12" FOREIGN KEY ("creatorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`);
        await queryRunner.query(`ALTER TABLE "test" ADD "userId" character varying NOT NULL`);
    }

}

我认为这个错误与typeorm entity metadata有关,也许清除它会修复这个错误,但到目前为止我还不知道如何做到这一点。

kg7wmglp

kg7wmglp1#

经过数小时的调试我发现问题不在于typeorm entity metadata,而在于User entity中的哪一列被Test实体中的creatorId列引用。默认情况下,引用的是integer类型的id字段,因此creatorIdid字段必须为相同类型,因此当迁移正在运行,它创建了creatorId字段类型为int。我通过引用uid字段修复了这个问题,该字段的类型为character varying,修改实体如下:

@ObjectType()
@Entity()
export class Test extends BaseEntity {

  @Field()
  @Column()
  creatorId: string;

  @ManyToOne(() => User, (user) => user.tests)
  @JoinColumn({ name: 'creatorId', referencedColumnName: 'uid' })
  creator: User;
}

相关问题