首先,我将简要解释我正在尝试做的事情以及相关的模型。
拥有一个 trackingIds 数组(10 个元素),使用这个 trackingId 和一个“免费”调色板创建一个染色体
考虑:
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'});
现在,我的代码看起来像这样:
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();
});
我注意到
availablePalettes
语句会检索我在此 forEach 的先前迭代中分配的调色板(这就是我决定每次重新加载项目实体的原因)。即使重新加载项目(返回免费可用的调色板),我也经历过这种情况。
检查我的日志我注意到:
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
我不确定这是否完全基于时间,但看起来 sequelize(肯定是由于性能原因)在我的调色板分配之前完成了我所有的染色体创建。这可能是 availablePalettes 返回在此 forEach() 的先前迭代中分配给 Chromosomes 的调色板的原因吗?
暂时就这些,先谢谢了!
最佳答案
Array 对象的 forEach func 不支持异步语法。使用“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();
}
此外,我建议您将事务用于此类批处理操作。
关于javascript - 使用 Sequelize 执行 INSERT 和 UPDATE 查询中的意外顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61329362/