简体   繁体   English

使用 Sequelize 的 INSERT 和 UPDATE 查询中的意外顺序

[英]Unexpected order in INSERT and UPDATE queries with Sequelize

First of all, I will explain briefly what I'm trying to do and models associated.首先,我将简要解释我正在尝试做什么以及相关的模型。

Having an array of trackingIds (10 elements), create a Chromosome with this trackingId and a "free" Palette拥有一个 trackingIds 数组(10 个元素),使用这个 trackingId 和一个“免费”调色板创建一个染色体

Considering:考虑:

Project.hasMany(models.Palette);
Project.hasMany(models.Chromosome);
Chromosome.hasOne(models.Palette);
Palette.belongsTo(models.Project, {foreignKey: 'projectId', as: 'project'});
Palette.belongsTo(models.Chromosome, {foreignKey: 'chromosomeId', as: 'chromosome'});

Now, my code looks something like this:现在,我的代码看起来像这样:

freeTrackingIds.forEach(async (trackingId) => {
    // Since the project has many palettes, I want to assign to the chromosome one palette that is free (this means, that has not been assigned to any chromosome yet).
    // I tried to reload() the project to fetch the changes in its palettes in previous iterations
    const availablePalettes = (await project.reload()).palettes.filter((palette) => !palette.chromosomeId);

    // Choosing a random palette from my available palettes. Yes, there might be better ways to achieve this. 
    const randomPalette = availablePalettes[Math.floor(Math.random() * availablePalettes.length)];

    // Creating the new chromosome for the project with the trackingId 
    const chromosome = await Chromosome.create({ projectId: project.id, trackingId: trackingId });

    // Linking the Palette to the chromosome
    randomPalette.chromosomeId = chromosome.id;
    await randomPalette.save();
  });

I have noticed that availablePalettes sentence would retrieve me palettes that were assigned in previous iterations of this forEach (that's why I decided to reload the project entity each time).我注意到, availablePalettes语句会检索我在此 forEach 的先前迭代中分配的调色板(这就是我决定每次都重新加载项目实体的原因)。

Even then reloading the project (that return with its free available palettes) I have experienced this.即使重新加载项目(返回其免费可用的调色板)我也经历过这一点。 Checking my logs I noticed that:检查我的日志我注意到:

Executing (default): INSERT INTO "Chromosomes" ("id","trackingId","elements","timesRequested","generation","createdAt","updatedAt","projectId") VALUES (DEFAULT,$1,$2,$3,$4,$5,$6,$7) RETURNING *;
Executing (default): INSERT INTO "Chromosomes" ("id","trackingId","elements","timesRequested","generation","createdAt","updatedAt","projectId") VALUES (DEFAULT,$1,$2,$3,$4,$5,$6,$7) RETURNING *;
Executing (default): INSERT INTO "Chromosomes" ("id","trackingId","elements","timesRequested","generation","createdAt","updatedAt","projectId") VALUES (DEFAULT,$1,$2,$3,$4,$5,$6,$7) RETURNING *;
Executing (default): INSERT INTO "Chromosomes" ("id","trackingId","elements","timesRequested","generation","createdAt","updatedAt","projectId") VALUES (DEFAULT,$1,$2,$3,$4,$5,$6,$7) RETURNING *;
Executing (default): INSERT INTO "Chromosomes" ("id","trackingId","elements","timesRequested","generation","createdAt","updatedAt","projectId") VALUES (DEFAULT,$1,$2,$3,$4,$5,$6,$7) RETURNING *;
Executing (default): INSERT INTO "Chromosomes" ("id","trackingId","elements","timesRequested","generation","createdAt","updatedAt","projectId") VALUES (DEFAULT,$1,$2,$3,$4,$5,$6,$7) RETURNING *;
Executing (default): INSERT INTO "Chromosomes" ("id","trackingId","elements","timesRequested","generation","createdAt","updatedAt","projectId") VALUES (DEFAULT,$1,$2,$3,$4,$5,$6,$7) RETURNING *;
Executing (default): INSERT INTO "Chromosomes" ("id","trackingId","elements","timesRequested","generation","createdAt","updatedAt","projectId") VALUES (DEFAULT,$1,$2,$3,$4,$5,$6,$7) RETURNING *;
Executing (default): INSERT INTO "Chromosomes" ("id","trackingId","elements","timesRequested","generation","createdAt","updatedAt","projectId") VALUES (DEFAULT,$1,$2,$3,$4,$5,$6,$7) RETURNING *;
Executing (default): UPDATE "Palettes" SET "chromosomeId"=$1,"updatedAt"=$2 WHERE "id" = $3
Executing (default): UPDATE "Palettes" SET "chromosomeId"=$1,"updatedAt"=$2 WHERE "id" = $3
Executing (default): UPDATE "Palettes" SET "chromosomeId"=$1,"updatedAt"=$2 WHERE "id" = $3
Executing (default): UPDATE "Palettes" SET "chromosomeId"=$1,"updatedAt"=$2 WHERE "id" = $3
Executing (default): UPDATE "Palettes" SET "chromosomeId"=$1,"updatedAt"=$2 WHERE "id" = $3
Executing (default): UPDATE "Palettes" SET "chromosomeId"=$1,"updatedAt"=$2 WHERE "id" = $3
Executing (default): UPDATE "Palettes" SET "chromosomeId"=$1,"updatedAt"=$2 WHERE "id" = $3
Executing (default): UPDATE "Palettes" SET "chromosomeId"=$1,"updatedAt"=$2 WHERE "id" = $3
Executing (default): UPDATE "Palettes" SET "chromosomeId"=$1,"updatedAt"=$2 WHERE "id" = $3

I'm not sure if this is exactly time-based but it looks like sequelize (due to performance reasons, surely) is doing all my chromosome creations before my palletes assignations.我不确定这是否完全基于时间,但看起来 sequelize(当然是由于性能原因)在分配托盘之前完成了我所有的染色体创建。 Could this be the reason why availablePalettes is returning palettes that were assigned to Chromosomes in previous iterations of this forEach()?这可能是为什么 availablePalettes 返回在此 forEach() 的先前迭代中分配给 Chromosomes 的调色板的原因吗?

That's all for now, thank you in advance!暂时就这些了,先谢谢了!

forEach func of an Array object does not support async syntax.数组 object 的 forEach 函数不支持异步语法。 Use 'for of':使用“为”:

forof (const trackingId of freeTrackingIds) {
// Since the project has many palettes, I want to assign to the chromosome one palette that is free (this means, that has not been assigned to any chromosome yet).
    // I tried to reload() the project to fetch the changes in its palettes in previous iterations
    const availablePalettes = (await project.reload()).palettes.filter((palette) => !palette.chromosomeId);

    // Choosing a random palette from my available palettes. Yes, there might be better ways to achieve this. 
    const randomPalette = availablePalettes[Math.floor(Math.random() * availablePalettes.length)];

    // Creating the new chromosome for the project with the trackingId 
    const chromosome = await Chromosome.create({ projectId: project.id, trackingId: trackingId });

    // Linking the Palette to the chromosome
    randomPalette.chromosomeId = chromosome.id;
    await randomPalette.save();  
}

Also I recommend you to use transaction for such batch operations.我还建议您将事务用于此类批处理操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM