我与媒体和标签有很多关系。我正在使用带有此版本sequelize的nodejs
"sequelize": "^5.8.6",
"pg": "^7.11.0",
"pg-hstore": "^2.3.2",
我想接收带有标签列表的新介质,并向每个Postgres表添加create相应的行。
我有这个模型定义:
export default class Media extends Model {
static init(sequelize) {
return super.init({
name: {
...
},
description: {
...
},
})
static associate(models) {
this.TagRelation = this.belongsToMany(models.Tag, { through:
models.MediaTag, as: 'MediaTags' });
}
}
export default class MediaTag extends Model {
static init(sequelize) {
return super.init({
}, {
sequelize,
timestamps: false,
});
}
static associate(models) {
this.belongsTo(models.Media, {
primaryKey: true,
});
this.belongsTo(models.Tag, {
primaryKey: true,
});
}
}
export default class Tag extends Model {
static init(sequelize) {
return super.init({
value: {
allowNull: false,
type: DataTypes.STRING,
unique: true,
},
});
}
static associate(models) {
this.belongsToMany(models.Media, { through: models.MediaTag, as: 'MediaTags' });
}
并希望这样做
newMedia = await Media.create({
...metadata,
type: metadata.type.toUpperCase(),
owner: ctx.user.id,
MediaTags: tagsValue,
},
{
include: [{
association: Media.TagRelation,
as: 'MediaTags',
ignoreDuplicates: true,
}],
});
这仅适用于新标签。如果标签值包含现有标签,则将其解冻
据我了解,这似乎是在创建媒体行,忽略现有标签(我之前创建过标签),但失败了,因为sequlize不会从数据库中的标签中检索tagId。
Executing (default): INSERT INTO "Media" ("id","name","description","likes","dislikes","status","location","owner","type","createdAt","updatedAt") VALUES (DEFAULT,$1,$2,$3,$4,$5,ST_GeomFromGeoJSON($6),$7,$8,$9,$10) RETURNING *;
Executing (default): INSERT INTO "Tags" ("id","value","createdAt","updatedAt") VALUES (DEFAULT,$1,$2,$3) ON CONFLICT DO NOTHING RETURNING *;
Executing (default): INSERT INTO "MediaTags" ("MediumId","TagId") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING *;
{ SequelizeDatabaseError: null value in column "TagId" violates not-null constraint
...
name: 'error',
length: 214,
severity: 'ERROR',
code: '23502',
detail:
'Failing row contains (32d5a5c2-e428-4268-a14f-c767b2acc2fb, null).',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: 'public',
table: 'MediaTags',
column: 'TagId',
dataType: undefined,
constraint: undefined,
file: 'execMain.c',
line: '2042',
routine: 'ExecConstraints',
sql:
'INSERT INTO "MediaTags" ("MediumId","TagId") VALUES ($1,$2) ON CONFLICT DO NOTHING RETURNING *;' },
...
如果我删除ignoreDupliates:
Executing (default): INSERT INTO "Media" ("id","name","description","likes","dislikes","status","location","owner","type","createdAt","updatedAt") VALUES (DEFAULT,$1,$2,$3,$4,$5,ST_GeomFromGeoJSON($6),$7,$8,$9,$10) RETURNING *;
Executing (default): INSERT INTO "Tags" ("id","value","createdAt","updatedAt") VALUES (DEFAULT,$1,$2,$3) RETURNING *;
{ SequelizeUniqueConstraintError: Validation error
...
name: 'SequelizeUniqueConstraintError',
errors:
[ ValidationErrorItem {
message: 'value must be unique',
type: 'unique violation',
path: 'value',
value: 'tagValue',
origin: 'DB',
instance: [Tag],
validatorKey: 'not_unique',
validatorName: null,
validatorArgs: [] } ],
我希望能够创建带有标签列表的新媒体。可以先创建此标签,然后再创建。如果标签不存在,则必须创建。