我有一个测试实体,它的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
有关,也许清除它会修复这个错误,但到目前为止我还不知道如何做到这一点。
1条答案
按热度按时间kg7wmglp1#
经过数小时的调试我发现问题不在于
typeorm entity metadata
,而在于User entity
中的哪一列被Test实体中的creatorId
列引用。默认情况下,引用的是integer
类型的id
字段,因此creatorId
和id
字段必须为相同类型,因此当迁移正在运行,它创建了creatorId字段类型为int。我通过引用uid
字段修复了这个问题,该字段的类型为character varying
,修改实体如下: