在 table 上插入或更新违反了外键约束 TelephoneContact
Insert or update on table violates foreign key constraint TelephoneContact
Objective
当我创建 client
.
时在 telephones
table 中创建
发生了什么
我有 3 个 table,分别是 clients
、contacts
和 telephones
。按照这张图片,我们可以看到 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种解法:
- 在电话中添加 2 个 fk 列,每个 table。然后,您必须决定其中之一是否必须为空,或者是否可以同时填充它们。
- 反转 FK 的方向,这样客户和联系人都有电话的 FK。这意味着他们可以毫不费力地指向同一部电话。
- 只需将电话号码迁移到客户和联系人 tables
并完全放下电话 table。毕竟是什么
分离电话号码的商业目的;生意如何
电话号码与电子邮件不同。
如果电话号码本身没有重要的业务流程,我会选择 #3。
Objective
当我创建 client
.
telephones
table 中创建
发生了什么
我有 3 个 table,分别是 clients
、contacts
和 telephones
。按照这张图片,我们可以看到 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种解法:
- 在电话中添加 2 个 fk 列,每个 table。然后,您必须决定其中之一是否必须为空,或者是否可以同时填充它们。
- 反转 FK 的方向,这样客户和联系人都有电话的 FK。这意味着他们可以毫不费力地指向同一部电话。
- 只需将电话号码迁移到客户和联系人 tables 并完全放下电话 table。毕竟是什么 分离电话号码的商业目的;生意如何 电话号码与电子邮件不同。
如果电话号码本身没有重要的业务流程,我会选择 #3。