Отношение TypeOrm OneToOne, вызывающее нежелательное встраивание столбцов - PullRequest
2 голосов
/ 20 июня 2020

У меня есть 2 объекта, которые имеют отношение OneToOne (User и CodUser), а у User есть JoinColumn. Когда TypeOrm синхронизирует этот шаблон с базой данных, он создает столбцы CodUser внутри пользователя, поэтому он встраивает CodUser И создает отдельную таблицу для объекта CodUser.

Я хочу, чтобы 2 объекта были отдельными, а столбцы в CodUser появляются только в таблице CodUser в моей (Postgres) базе данных. Я считаю, что это точный шаблон, используемый TypeOrm для демонстрации отношений OneToOne, но, похоже, что-то не так.

user.entity.ts

@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;

@Column({ unique: true })
email: string;

@Column({ nullable: true })
avatar: string;

@Column()
password: string;

@Column({
    type: "text",
    array: true,
    nullable: false,
    default: `{${Role.Player}}`
})
roles: Role[];

@OneToOne((type) => CodUser, {
    cascade: true
})
@JoinColumn()
codUser: CodUser;

@Column({ default: 0 })
invalidLoginAttempts: number;

@Column({ nullable: true })
activationCode: string;

@Column({ nullable: false, default: false })
active: boolean;

@Column({ nullable: true })
lockedUntil: Date;

@Column({ nullable: true })
lastLoginAttemptAt: Date;

@OneToMany((type) => ChallangeUser, (challangeUser) => challangeUser.user)
challanges: ChallangeUser[];

@CreateDateColumn({ type: "timestamp" })
createdAt: Date;

@UpdateDateColumn({ type: "timestamp" })
updatedAt: Date;

constructor(email: string, username: string, platform: Platform, password: string) {
    this.email = email;
    this.codUser = new CodUser(username, platform);
    this.password = password;
}
}

cod- user.entity.ts

@Entity()
export class CodUser {
@PrimaryGeneratedColumn()
id: string;

@Column({ unique: true })
username: string;

@Column({ nullable: false })
platform: Platform;

@Column({ type: "jsonb", nullable: true })
recentWarzoneMatches: object[];

@Column({ nullable: true })
recentWarzoneMatchesSyncedAt: Date;

constructor(username: string, platform: Platform) {
    this.username = username;
    this.platform = platform;
}
}

Результат:

Проводник базы данных

Транзакция при синхронизации:

query: START TRANSACTION
query: SELECT * FROM current_schema()
query: SELECT * FROM "information_schema"."tables" WHERE ("table_schema" = 'public' AND "table_name" = 'challange') OR ("table_schema" = 'public' AND "table_name" = 'challange_user') OR ("table_schema" = 'public' AND "table_name" = 'cod_user') OR ("table_schema" = 'public' AND "table_name" = 'user') OR ("table_schema" = 'public' AND "table_name" = 'user') OR ("table_schema" = 'public' AND "table_name" = 'challange') OR ("table_schema" = 'public' AND "table_name" = 'challange_user')
query: SELECT *, ('"' || "udt_schema" || '"."' || "udt_name" || '"')::"regtype" AS "regtype" FROM "information_schema"."columns" WHERE ("table_schema" = 'public' AND "table_name" = 'challange') OR ("table_schema" = 'public' AND "table_name" = 'challange_user') OR ("table_schema" = 'public' AND "table_name" = 
'cod_user') OR ("table_schema" = 'public' AND "table_name" = 'user') OR ("table_schema" = 'public' AND "table_name" = 'user') OR ("table_schema" = 'public' AND "table_name" = 'challange') OR ("table_schema" = 'public' AND "table_name" = 'challange_user')
query: SELECT "ns"."nspname" AS "table_schema", "t"."relname" AS "table_name", "cnst"."conname" AS "constraint_name", pg_get_constraintdef("cnst"."oid") AS "expression", CASE "cnst"."contype" WHEN 'p' THEN 'PRIMARY' WHEN 'u' THEN 'UNIQUE' WHEN 'c' THEN 'CHECK' WHEN 'x' THEN 'EXCLUDE' END AS "constraint_type", "a"."attname" AS "column_name" FROM "pg_constraint" "cnst" INNER JOIN "pg_class" "t" ON "t"."oid" = "cnst"."conrelid" INNER JOIN "pg_namespace" "ns" ON "ns"."oid" = "cnst"."connamespace" LEFT JOIN "pg_attribute" "a" ON "a"."attrelid" = "cnst"."conrelid" AND "a"."attnum" = ANY ("cnst"."conkey") WHERE "t"."relkind" = 'r' AND (("ns"."nspname" = 'public' AND "t"."relname" = 'challange') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'challange_user') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'cod_user') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'user') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'user') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'challange') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'challange_user'))
query: SELECT "ns"."nspname" AS "table_schema", "t"."relname" AS "table_name", "i"."relname" AS "constraint_name", "a"."attname" AS "column_name", CASE "ix"."indisunique" WHEN 't' THEN 'TRUE' ELSE'FALSE' END AS "is_unique", pg_get_expr("ix"."indpred", "ix"."indrelid") AS "condition", "types"."typname" AS "type_name" FROM "pg_class" "t" INNER JOIN "pg_index" "ix" ON "ix"."indrelid" = "t"."oid" INNER JOIN "pg_attribute" "a" ON "a"."attrelid" = "t"."oid"  AND "a"."attnum" = ANY ("ix"."indkey") INNER JOIN "pg_namespace" "ns" ON "ns"."oid" = "t"."relnamespace" INNER JOIN "pg_class" "i" ON "i"."oid" = "ix"."indexrelid" INNER JOIN "pg_type" "types" ON "types"."oid" = "a"."atttypid" LEFT JOIN "pg_constraint" "cnst" ON "cnst"."conname" = "i"."relname" WHERE "t"."relkind" = 'r' AND "cnst"."contype" IS NULL AND (("ns"."nspname" = 'public' AND "t"."relname" = 'challange') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'challange_user') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'cod_user') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'user') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'user') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'challange') OR ("ns"."nspname" = 'public' AND "t"."relname" = 'challange_user'))
query: SELECT "con"."conname" AS "constraint_name", "con"."nspname" AS "table_schema", "con"."relname" AS "table_name", "att2"."attname" AS "column_name", "ns"."nspname" AS "referenced_table_schema", "cl"."relname" AS "referenced_table_name", "att"."attname" AS "referenced_column_name", "con"."confdeltype" AS "on_delete", "con"."confupdtype" AS "on_update", "con"."condeferrable" AS "deferrable", "con"."condeferred" AS "deferred" FROM ( SELECT UNNEST ("con1"."conkey") AS "parent", UNNEST ("con1"."confkey") AS "child", "con1"."confrelid", "con1"."conrelid", "con1"."conname", "con1"."contype", "ns"."nspname", "cl"."relname", "con1"."condeferrable", CASE WHEN "con1"."condeferred" THEN 'INITIALLY DEFERRED' ELSE 'INITIALLY IMMEDIATE' END as condeferred, CASE "con1"."confdeltype" WHEN 'a' THEN 'NO ACTION' WHEN 'r' THEN 'RESTRICT' WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT' END as "confdeltype", CASE "con1"."confupdtype" WHEN 'a' THEN 'NO ACTION' WHEN 'r' THEN 'RESTRICT' WHEN 'c' THEN 'CASCADE' WHEN 'n' THEN 'SET NULL' WHEN 'd' THEN 'SET DEFAULT' END as "confupdtype" FROM "pg_class" "cl" INNER JOIN "pg_namespace" "ns" ON "cl"."relnamespace" = "ns"."oid" INNER JOIN "pg_constraint" "con1" ON "con1"."conrelid" = "cl"."oid" WHERE "con1"."contype" = 'f' AND (("ns"."nspname" = 'public' AND "cl"."relname" = 'challange') OR ("ns"."nspname" = 'public' AND "cl"."relname" = 'challange_user') OR ("ns"."nspname" = 'public' AND "cl"."relname" = 'cod_user') OR ("ns"."nspname" = 'public' AND "cl"."relname" = 'user') OR ("ns"."nspname" = 'public' AND "cl"."relname" = 'user') OR ("ns"."nspname" = 'public' AND "cl"."relname" = 'challange') OR ("ns"."nspname" = 'public' AND "cl"."relname" = 'challange_user')) ) "con" INNER JOIN "pg_attribute" "att" ON "att"."attrelid" = "con"."confrelid" AND "att"."attnum" = "con"."child" INNER JOIN "pg_class" "cl" ON "cl"."oid" = "con"."confrelid" INNER JOIN "pg_namespace" "ns" ON "cl"."relnamespace" = "ns"."oid" INNER JOIN "pg_attribute" "att2" ON "att2"."attrelid" = "con"."conrelid" AND "att2"."attnum" = "con"."parent"
query: SELECT * FROM "information_schema"."tables" WHERE "table_schema" = current_schema() AND "table_name" = 'typeorm_metadata'
query: ALTER TABLE "user" DROP CONSTRAINT "FK_c8521799e9a87cab5983c57ba1c"
query: ALTER TABLE "challange_user" DROP CONSTRAINT "FK_0c9f41f81c2f9cadd1154c90499"
query: ALTER TABLE "challange" DROP COLUMN "userLimit"
query: ALTER TABLE "user" DROP CONSTRAINT "UQ_c8521799e9a87cab5983c57ba1c"
query: ALTER TABLE "user" DROP COLUMN "custom_cod_user"
query: ALTER TABLE "user" DROP CONSTRAINT "UQ_78a916df40e02a9deb1c4b75edb"
query: ALTER TABLE "user" DROP COLUMN "username"
query: ALTER TABLE "user" DROP COLUMN "platform"
query: ALTER TABLE "user" DROP COLUMN "recentWarzoneMatches"
query: ALTER TABLE "user" DROP COLUMN "recentWarzoneMatchesSyncedAt"
query: ALTER TABLE "user" DROP COLUMN "roles"
query: ALTER TABLE "challange" DROP COLUMN "slots"
query: ALTER TABLE "challange_user" DROP COLUMN "isConfirmed"
query: ALTER TABLE "challange_user" DROP COLUMN "challangeId"
query: ALTER TABLE "challange" ADD "slots" integer NOT NULL DEFAULT -1
query: ALTER TABLE "challange_user" ADD "isConfirmed" boolean NOT NULL DEFAULT false
query: ALTER TABLE "challange_user" ADD "challangeId" uuid
query: ALTER TABLE "user" ADD "roles" text array NOT NULL DEFAULT '{player}'::text[]
query: ALTER TABLE "user" ADD "codUserId" integer
query: ALTER TABLE "user" ADD CONSTRAINT "UQ_4ee803ddc575ea07a96a0aa5f40" UNIQUE ("codUserId")
query: ALTER TABLE "user" ADD "username" character varying NOT NULL
query: ALTER TABLE "user" ADD CONSTRAINT "UQ_78a916df40e02a9deb1c4b75edb" UNIQUE ("username")
query: ALTER TABLE "user" ADD "platform" character varying NOT NULL
query: ALTER TABLE "user" ADD "recentWarzoneMatches" jsonb
query: ALTER TABLE "user" ADD "recentWarzoneMatchesSyncedAt" TIMESTAMP
query: ALTER TABLE "challange" ADD "userLimit" integer NOT NULL DEFAULT -1
query: ALTER TABLE "challange_user" ADD CONSTRAINT "FK_0c9f41f81c2f9cadd1154c90499" FOREIGN KEY ("challangeId") REFERENCES "challange"("id") ON DELETE NO ACTION ON UPDATE NO ACTION
query: ALTER TABLE "user" ADD CONSTRAINT "FK_4ee803ddc575ea07a96a0aa5f40" FOREIGN KEY ("codUserId") REFERENCES "cod_user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION
query: COMMIT

1 Ответ

0 голосов
/ 20 июня 2020

Удаление папки / dist в моем проекте Nest JS решило проблему, похоже, что это все-таки проблема Nest JS.

...