【问题标题】:Insert or update on table violates foreign key constraint TelephoneContact在表上插入或更新违反外键约束 TelephoneContact
【发布时间】:2020-12-02 12:43:21
【问题描述】:

目标

当我创建client 时,在telephones 表中创建。

发生了什么

我有 3 个表,分别称为 clientscontactstelephones。根据这张图片,我们可以看到owner_id 可以是contacts.id 和/或clients.id。但是当我尝试创建client 时,client 已创建但未在telephones 表中插入数据。但是显示这个错误

{
  "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;

【问题讨论】:

    标签: typescript postgresql typeorm


    【解决方案1】:

    不能按照所述创建电话表。您正在尝试将列 owner_id 定义为 contacts 表的 FK 和 clients 表的 FK。 Postgres 无法做到这一点。该列可以是任一表的 FK,但必须始终是指定表的 FK。我不知道您的 ORM 如何处理此问题,但看起来它会导致联系人的 FK(实际表 ddl 将显示定义)。当您然后插入客户端时,会因为电话值不存在联系人而违反 FK。

    有3种解决方案:

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

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

    【讨论】:

      猜你喜欢
      • 2011-01-27
      • 2015-08-19
      • 2020-09-07
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-06
      • 2019-06-16
      相关资源
      最近更新 更多