Неожиданный порядок в запросах INSERT и UPDATE с Sequelize - PullRequest
0 голосов
/ 20 апреля 2020

Прежде всего, я кратко объясню, что я пытаюсь сделать и связанные с ними модели.

Имея массив 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

Я не уверен, что это точно по времени, но похоже, что секвелиз (из-за соображений производительности, безусловно) выполняет все мои хромосомные создания перед моими паллетами ассигнации. Может ли это быть причиной того, что availablePalettes возвращает палитры, которые были назначены хромосомам в предыдущих итерациях этого forEach ()?

На этом пока все, заранее спасибо!

1 Ответ

0 голосов
/ 20 апреля 2020

forEach fun c объекта Array не поддерживает асинхронный c синтаксис. Используйте '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();  
}

Также я рекомендую использовать транзакцию для таких пакетных операций.

...