TypeORMを使用していて、現在3つのエンティティでデータベースを設計したいと考えています。複製用のリポジトリを作成しました
更新
2つの小さな実体でそれを再現することができました
これについての詳細は以下をご覧ください
つまり、まず最初にmoduleエンティティを作成します。これはいくつかの基本的なフィールドのみを格納するため、小さなものです。
@Entity()
export class Module extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
public id: string;
// some other fields without references
}
次にgraphエンティティがあります。これは複数のgraphNodesを保持しています。したがって、複数のグラフを作成でき、それぞれに独自のgraphNodeがあります。グラフ自体は、どのgraphNodeがグラフの最初のものかを知る必要があります。そこで、graphNodeエンティティへの外部キー参照を設定しようとしました。
。
@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は、1つのグラフ内のモジュールを表します。また、その後継者successGraphNodeIdおよびerrorGraphNodeIdについても認識します。ノードに重要なのは、このエンティティに複合主キーがあることです。これは、graphNodeをフェッチしたい場合は、グラフIDも渡す必要があるためです。基本的にこれらはユースケースです
。
@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)
エンティティのデザインが正しくないようです。誰かがここで何が間違っているか何が欠けているか知っていますか?さらに情報が必要な場合や、複製リポジトリを更新する必要がある場合は、お知らせください。
前もって感謝します
更新
2つの小さな実体でそれを再現することができました。グラフには関係しかない
@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プライマリ列を基本的な列に変換したくないのは、データベースの設計が悪いためです...
エンティティで外部キー制約を次のように使用しています。
@ManyToOne(
() => GraphNode,
graphNode => graphNode.id,
)
と他のエンティティでそれぞれ。現在のデータベースがこのルールを満たしていないため、エラーが発生しています。したがって、これを機能させる最も簡単な方法は次のとおりです。
これを行うと、新しく作成されたすべてのレコードがデータベースの更新された制約に従って動作します。これがうまくいくことを願っています。