在 table 上插入或更新违反了外键约束 TelephoneContact

Insert or update on table violates foreign key constraint TelephoneContact

Objective

当我创建 client.

时在 telephones table 中创建

发生了什么

我有 3 个 table,分别是 clientscontactstelephones。按照这张图片,我们可以看到 owner_id 可以是 contacts.id and/or clients.id。但是当我尝试创建 client 时,会创建 client 但不会在 telephones table 中插入数据。但是显示这个错误

{
  "error": "insert or update on table \"telephones\" violates foreign key constraint \"TelephoneContact\""
}

迁移

import {
  MigrationInterface,
  QueryRunner,
  TableColumn,
  TableForeignKey,
} from 'typeorm';

export default class AddOwnerIdToTelephones1597250413640
  implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.addColumn(
      'telephones',
      new TableColumn({
        name: 'owner_id',
        type: 'uuid',
        isNullable: false,
      }),
    );

    await queryRunner.createForeignKey(
      'telephones',
      new TableForeignKey({
        name: 'TelephoneClient',
        columnNames: ['owner_id'],
        referencedColumnNames: ['id'],
        referencedTableName: 'clients',
        onDelete: 'CASCADE',
        onUpdate: 'CASCADE',
      }),
    );

    await queryRunner.createForeignKey(
      'telephones',
      new TableForeignKey({
        name: 'TelephoneContact',
        columnNames: ['owner_id'],
        referencedColumnNames: ['id'],
        referencedTableName: 'contacts',
        onDelete: 'CASCADE',
        onUpdate: 'CASCADE',
      }),
    );
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.dropForeignKey('telephones', 'TelephoneContact');
    await queryRunner.dropForeignKey('telephones', 'TelephoneClient');
    await queryRunner.dropColumn('telephones', 'owner_id');
  }
}

电话型号

import {
  PrimaryGeneratedColumn,
  Column,
  Entity,
  ManyToOne,
  JoinColumn,
} from 'typeorm';

import Client from './Client';
import Contact from './Contact';

@Entity('telephones')
class Telephone {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  telephone_number: string;

  @ManyToOne(() => Client, client => client.id)
  @ManyToOne(() => Contact, contact => contact.id)
  @JoinColumn({ name: 'owner_id' })
  owner_id: string;
}

export default Telephone;

不能按照描述创建电话table。您正在尝试将列 owner_id 定义为联系人 table 的外键和客户 table 的外键。 Postgres 做不到这一点。该列可以是 table 的外键,但必须 始终 是指定 table 的外键。我不知道你的 ORM 是如何处理这个的,但看起来它会导致联系人的 FK(实际 table ddl 会显示定义)。当您随后插入到客户端时,会出现 FK 违规,因为电话值不存在联系人。

有3种解法:

  1. 在电话中添加 2 个 fk 列,每个 table。然后,您必须决定其中之一是否必须为空,或者是否可以同时填充它们。
  2. 反转 FK 的方向,这样客户和联系人都有电话的 FK。这意味着他们可以毫不费力地指向同一部​​电话。
  3. 只需将电话号码迁移到客户和联系人 tables 并完全放下电话 table。毕竟是什么 分离电话号码的商业目的;生意如何 电话号码与电子邮件不同。

如果电话号码本身没有重要的业务流程,我会选择 #3。