QueryFailedError:在表“graph”上插入或更新违反了外键约束“FK_0e40......”
Posted
技术标签:
【中文标题】QueryFailedError:在表“graph”上插入或更新违反了外键约束“FK_0e40......”【英文标题】:QueryFailedError: insert or update on table "graph" violates foreign key constraint "FK_0e40......" 【发布时间】:2020-06-28 19:11:00 【问题描述】:我创建了一个非常小的reproduction repository。
请在下面查看我可能的解决方法。
我有一个图和一个图节点实体。图只知道它的起始图节点,而节点本身知道它属于哪个图及其后继图。
@Entity()
export class Graph extends BaseEntity
@PrimaryGeneratedColumn("uuid")
public id: string;
@Column( nullable: true )
public startNodeId?: string;
@ManyToOne(() => GraphNode)
@JoinColumn( name: "startNodeId" )
public startNode?: GraphNode;
@Entity()
export class GraphNode extends BaseEntity
@PrimaryGeneratedColumn("uuid")
public id: string;
@PrimaryColumn("uuid")
public graphId: string;
@ManyToOne(() => Graph, onDelete: "CASCADE" )
@JoinColumn( name: "graphId" )
public graph: Graph;
@Column( nullable: true )
public successorGraphNodeId?: string;
@ManyToOne(() => GraphNode)
@JoinColumn( name: "successorGraphNodeId" )
public successorGraphNode?: GraphNode;
如您所见,图表的 startnode 可能为空。此外,图形节点可能没有后继节点,因此该字段也可能为空。图节点具有复合主键很重要,因为它始终属于一个图。
我创建了一些非常基本的 CRUD 存储库操作来创建图形和图形节点。稍后我想更新该图的起始节点 ID。
图节点存储库只是创建了一个新实体
public createGraphNode(graphId: string, successorGraphNodeId?: string): Promise<GraphNode>
const graphNode: GraphNode = new GraphNode();
graphNode.graphId = graphId;
graphNode.successorGraphNodeId = successorGraphNodeId;
return graphNode.save();
图形存储库创建一个新实体并能够更新其起始节点 ID
public createGraph(startNodeId?: string): Promise<Graph>
const graph: Graph = new Graph();
graph.startNodeId = startNodeId;
return graph.save();
public updateStartNodeId(graphId: string, startNodeId: string): Promise<UpdateResult>
return this.update(graphId,
startNodeId
);
在运行应用程序时,我会创建一个新图表。之后,我创建一个新的图形节点并将图形 ID 分配给它。此图节点没有后继节点。最后我将图节点指定为图开始节点。
const graph: Graph = await graphsRepository.createGraph();
const graphNode: GraphNode = await graphNodesRepository.createGraphNode(graph.id);
await graphsRepository.updateStartNodeId(graph.id, graphNode.id);
这样做我得到以下数据库错误
QueryFailedError: 在表“graph”上插入或更新违反了外部 关键约束“FK_0e4022833a9efc062c01637e552”
看来我的实体设计是错误的。有人知道怎么解决吗?
提前致谢
我可能会解决它
图形实体
通过referencedColumnName: "id"
创建对PK的引用
@ManyToOne(() => GraphNode)
@JoinColumn( name: "startNodeId", referencedColumnName: "id" )
public startNode?: GraphNode;
图节点实体
对后继图节点执行相同操作
@ManyToOne(() => GraphNode)
@JoinColumn( name: "successorGraphNodeId", referencedColumnName: "id" )
public successorGraphNode?: GraphNode;
还将Unique
装饰器添加到实体并将id
字段标记为唯一
@Unique(["id"])
我唯一的问题是我不知道为什么要这样解决。
不知道为什么要通过referencedColumnName: "id"
引用被引用表的PK,这个应该很明显了
我也不知道为什么我必须通过@Unique(["id"])
将 id 列标记为唯一,因为该字段将始终是唯一的
【问题讨论】:
您是否尝试在 @OneToMany 属性中同时设置 onDelete: "CASCADE" 和 cascade: ["insert", "update", "remove" ]? @Aurinxki 这会有所作为吗?我专注于我在修复解决方案中提出的问题:) 【参考方案1】:在您的 .Save() 中将 id 作为参数传递,否则它会认为您正在创建新数据。
【讨论】:
以上是关于QueryFailedError:在表“graph”上插入或更新违反了外键约束“FK_0e40......”的主要内容,如果未能解决你的问题,请参考以下文章
在 TypeORM 上接收“QueryFailedError:重复键值违反唯一约束”“pg_type_typname_nsp_index”错误