如何在Sequelize-Typescript中设置account与feedItem为复合主键兼外键?
问题描述
我在Sequelize(使用sequelize-typescript)中有一个存储点赞/点踩投票的模型,需要记录被操作的帖子及操作用户。当前的likeDislike.model.ts代码如下:
/* eslint import/no-cycle: "off" */ import { DataTypes } from 'sequelize'; import { Model, PrimaryKey, Column, Table, Default, IsUUID, BelongsTo, Unique, } from 'sequelize-typescript'; import { Account, FeedItem } from 'data/models'; @Table({ createdAt: false, freezeTableName: true, tableName: 'feed_item_like_dislike_votes', updatedAt: false, }) export default class FeedItemLikeDislikeVote extends Model { @Column vote: boolean; @BelongsTo(() => Account, { foreignKey: { name: 'accountId', allowNull: false }, as: 'account_', }) @Column({ type: DataTypes.UUID, field: 'account_id' }) account: Account; @BelongsTo(() => FeedItem, { foreignKey: { name: 'feedItemId', allowNull: false }, as: 'feedItem_', }) @Column({ type: DataTypes.UUID, field: 'feed_item_id' }) feedItem: FeedItem; }
请问如何将account和feedItem设置为复合主键,同时让它们分别作为Account和FeedItem表的外键?
解决方案
要实现复合主键同时保留外键关联,只需做这几点修改:
- 给
accountId和feedItemId字段分别加上@PrimaryKey装饰器,明确把这两个外键字段设为复合主键的组成部分(别直接给关联对象标记主键,要针对外键字段操作)。 - 调整
@BelongsTo的配置,保证外键映射准确。
修改后的完整代码如下:
/* eslint import/no-cycle: "off" */ import { DataTypes } from 'sequelize'; import { Model, PrimaryKey, Column, Table, BelongsTo, } from 'sequelize-typescript'; import { Account, FeedItem } from 'data/models'; @Table({ createdAt: false, freezeTableName: true, tableName: 'feed_item_like_dislike_votes', updatedAt: false, }) export default class FeedItemLikeDislikeVote extends Model { @Column vote: boolean; // 标记accountId为复合主键之一,同时作为Account表的外键 @PrimaryKey @Column({ type: DataTypes.UUID, field: 'account_id', allowNull: false }) accountId: string; @BelongsTo(() => Account, { foreignKey: 'accountId', as: 'account_', }) account: Account; // 标记feedItemId为复合主键之一,同时作为FeedItem表的外键 @PrimaryKey @Column({ type: DataTypes.UUID, field: 'feed_item_id', allowNull: false }) feedItemId: string; @BelongsTo(() => FeedItem, { foreignKey: 'feedItemId', as: 'feedItem_', }) feedItem: FeedItem; }
关键说明:
- 复合主键的设置方式是给每个组成字段单独加
@PrimaryKey,Sequelize会自动把它们组合成复合主键。 - 必须明确声明外键字段(
accountId、feedItemId),不能直接在关联对象属性上添加主键装饰器,这样才能同时保证外键关联正常、复合主键设置正确。 @BelongsTo的foreignKey参数要和对应的字段名完全一致,避免出现映射错误。
内容的提问来源于stack exchange,提问作者PirateApp
相关产品推荐
相关产品推荐

