【发布时间】:2020-06-12 08:16:39
【问题描述】:
我正在使用 TypeORM,并希望使用当前三个实体来设计我的数据库。我创建了一个用于复制的存储库
Github reproduction repository
更新
我只用两个小实体就能重现它
更多信息在下面
首先我有一个 module 实体。这个很小,因为它只存储了一些基本字段。
@Entity()
export class Module extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
public id: string;
// some other fields without references
}
接下来我有一个 graph 实体。这个持有多个 graphNodes。所以你可以有多个图,每个图都有自己的graphNodes。图本身需要知道哪个 graphNode 是图中的第一个。因此,我尝试设置对 graphNode 实体的外键引用。
- 可以有多个图表
- 每个图都有一个graphNode作为起始节点
- 每个图有多个 graphNodes
.
@Entity()
export class Graph extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
public id: string;
@Column({ nullable: true })
public startNodeId?: string;
@ManyToOne(
() => GraphNode,
graphNode => graphNode.id,
)
@JoinColumn({ name: 'startNodeId' })
public startNode: GraphNode;
}
最后一个实体是 graphNodes 实体。每个 graphNode 代表一个图中的一个模块。它还知道它的继任者 successGraphNodeId 和 errorGraphNodeId。这个实体有一个复合主键的节点很重要,因为如果你想获取一个graphNode,你也必须传入graph id。基本上这些是用例
- 一个graphNode代表一个模块
- 每个图有多个 graphNodes
- graphNode 可以将自己作为后继对象引用(成功/错误)
- graphNode 后继可以为 null(成功/错误)
- graphNode 后继者必须是 this 图中已经存在的 graphNode
.
@Entity()
export class GraphNode extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
public id: string;
@PrimaryColumn()
public graphId: string; // composite key https://github.com/typeorm/typeorm/blob/master/sample/sample27-composite-primary-keys/entity/Post.ts
@ManyToOne(
() => Graph,
graph => graph.id,
)
@JoinColumn({ name: 'graphId' })
public graph: Graph;
@Column()
public moduleId: string;
@ManyToOne(
() => Module,
module => module.id,
)
@JoinColumn({ name: 'moduleId' })
public module: Module;
@Column({ nullable: true })
public successGraphNodeId?: string;
@ManyToOne(
() => GraphNode,
graphNode => graphNode.id,
)
@JoinColumn({ name: 'successGraphNodeId' })
public successGraphNode?: GraphNode;
@Column({ nullable: true })
public errorGraphNodeId?: string;
@ManyToOne(
() => GraphNode,
graphNode => graphNode.id,
)
@JoinColumn({ name: 'errorGraphNodeId' })
public errorGraphNode?: GraphNode;
}
不幸的是,在运行应用程序时遇到此错误
QueryFailedError: Foreign key constraint »FK_0e4022833a9efc062c01637e552« cannot be implemented
at new QueryFailedError (...\references-reproduction\node_modules\typeorm\error\QueryFailedError.js:11:28)
at Query.callback (...\references-reproduction\node_modules\typeorm\driver\postgres\PostgresQueryRunner.js:176:38)
at Query.handleError (...\references-reproduction\node_modules\pg\lib\query.js:145:17)
at Connection.connectedErrorMessageHandler (...\references-reproduction\node_modules\pg\lib\client.js:214:17)
at Connection.emit (events.js:223:5)
at Socket.<anonymous> (...\references-reproduction\node_modules\pg\lib\connection.js:134:12)
at Socket.emit (events.js:223:5)
at addChunk (_stream_readable.js:309:12)
at readableAddChunk (_stream_readable.js:290:11)
at Socket.Readable.push (_stream_readable.js:224:10)
看来我的实体设计不正确。有人知道这里有什么问题或遗漏吗?如果您需要更多信息或者我是否应该更新我的复制存储库,请告诉我。
提前致谢
更新
我能够用两个小实体复制它。图之间只有关系
@Entity()
export class Graph extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
public id: string;
@Column({ nullable: true })
public startNodeId?: string;
@ManyToOne(
() => Node,
node => node.id,
)
@JoinColumn({ name: 'startNodeId' })
public node: Node;
}
及其节点
@Entity()
export class Node extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
public id: string;
@PrimaryColumn()
public graphId: string;
@ManyToOne(
() => Graph,
graph => graph.id,
)
@JoinColumn({ name: 'graphId' })
public graph: Graph;
}
如前所述,问题似乎依赖于复合主键。我不想将节点的 graphId 主列转换为基本列,因为这将是糟糕的数据库设计...
【问题讨论】:
标签: sql postgresql typeorm