适当的 Sequelize 流程以避免重复行?

Proper Sequelize flow to avoid duplicate rows?

我在我的节点 js 服务器中使用 Sequelize。我最终遇到了验证错误,因为我的代码尝试两次写入记录而不是创建一次然后更新它,因为它已经在数据库 (Postgresql) 中。

这是我在请求运行时使用的流程:

const latitude = req.body.latitude;
var metrics = await models.user_car_metrics.findOne({ where: { user_id: userId, car_id: carId } }) 

if (metrics) {
    metrics.latitude = latitude;
    .....
} else {
    metrics = models.user_car_metrics.build({
        user_id: userId,
        car_id: carId,
        latitude: latitude
        ....
    });
}

var savedMetrics = await metrics();
return res.status(201).json(savedMetrics);

有时,如果客户端非常快地调用端点两次或更多次,上面的端点会尝试在 user_car_metrics 中保存 两个新行 ,使用相同的 user_idcar_id,都在 tables usercar.

上 FK

我有一个约束:

ALTER TABLE user_car_metrics DROP CONSTRAINT IF EXISTS user_id_car_id_unique, ADD CONSTRAINT user_id_car_id_unique UNIQUE (car_id, user_id);

要点是,给定的 user_idcar_id 对只能有一个条目。

因此,我开始看到验证问题,在查看并添加日志后,我意识到上面的代码在 table 中添加了重复项(没有约束)。如果约束存在,当上面的代码尝试插入重复记录时,我会收到验证错误。

问题是,如何避免这个问题?我如何构建代码以便它不会尝试创建重复记录。有没有办法序列化这个?

如果您有一个唯一约束,那么您可以使用 upsert 来插入或更新记录,具体取决于您是否有一条记录具有相同的主键值或唯一约束中的列值。

await models.user_car_metrics.upsert({
        user_id: userId,
        car_id: carId,
        latitude: latitude
        ....
    })

upsert

PostgreSQL - Implemented with ON CONFLICT DO UPDATE. If update data contains PK field, then PK is selected as the default conflict key. Otherwise, first unique constraint/index will be selected, which can satisfy conflict key requirements.