Sequelize ORM: использование отложенных ограничений для таблицы соединений - PullRequest
0 голосов
/ 27 мая 2020

Я пытаюсь использовать ассоциацию Many: Many с Sequelize (вместо Postgre db).

Я хочу создать заведение и связать его с пользователь в одной транзакции. Места проведения и пользователи настроены как обычные модели Sequelize, и каждая из них настроена на «ownToMany» для другой с помощью соединительной таблицы «userVenue».

Проблема в том, что я не могу создать новую объект , а также его первая ассоциация пользователь в той же транзакции. Postgre вызывает следующую ошибку:

insert or update on table "userVenues" violates foreign key constraint "userVenues_venueId_fkey"

, поскольку новое место проведения еще не было зафиксировано.

Думаю, мне нужно установить ограничения внешнего ключа на "userId" и "VenueId" в таблице соединений "userVenues", чтобы быть изначально отложенными согласно Sequelize docs , однако, поскольку Sequelize автоматически определяет "userId" и "placeId" таблицы соединений, я могу 'Не понимаю, как установить их как INITIALLY_DEFERRABLE.

Я попытался просто установить транзакцию на SET_DEFERRED (как и в случае c), и я вижу в журналах, что он выдает команда «SET CONSTRAINTS ALL DEFERRED» для БД, однако, поскольку Sequelize, похоже, по умолчанию устанавливает ограничения NOT (отложено), я все еще терплю неудачу с той же ошибкой. Если я не использую транзакцию, две последовательные INSERTS работают нормально.

Есть ли способ определить эти внешние ключи как отложенные? Или я неправильно подхожу к этому?

Большое спасибо!

Соответствующий код ниже:

  // *** ASSOCIATIONS ***
  
  // The Venue association
  Venue.belongsToMany(models.user, {
    through: models.userVenue,
  });
  
    // The User association
  User.belongsToMany(models.venue, {
    through: models.userVenue,
  });
  
  
  
  // *** THE TRANSACTION ***
  const newVenue = await db.sequelize.transaction(
  { deferrable: Sequelize.Deferrable.SET_DEFERRED },
  async (t) => {
    const newRow = await db.venue.create(
      { ...payload },
      { transaction: t }
    );

    await newRow.addUser(
      socket.user,
      {
        through: { permit: 'edit' },
      },
      { transaction: t }
    );

    return newRow;
  }

1 Ответ

0 голосов
/ 27 мая 2020

После дальнейшего исследования выяснилось, что это может быть ошибка в Sequelize: https://github.com/sequelize/sequelize/issues/8194

Хотя это было помечено как ошибка, исправления пока нет. Один полезный пользователь ответил на мое сообщение в этой ветке с потенциальным исправлением, но на данный момент нет запроса на перенос.

Временное решение, которое я сейчас использую, если кто-то сочтет его полезным, - это запустить этот необработанный запрос после DB Syn c, чтобы изменить ограничение. Это требует знания имени ограничения.

    await sequelize.query(
      'ALTER TABLE "userVenues" ALTER CONSTRAINT "userVenues_venueId_fkey" DEFERRABLE INITIALLY DEFERRED'
    );
...