Я написал API в Express.js. Я использовал Sequelize. У меня есть метод создания:

exports.story = async (req, res) => {
  try {
    const userId = await authController.userId(req);
    const { type, firstTeam, secondTeam, date, place, leagueId } = req.body;
    const newEvent = {
      userId,
      type,
      firstTeam,
      secondTeam,
      date,
      place,
      leagueId,
    };

    const storeLeague = await models.Event.create(newEvent);
    return res.status(200).json(storeLeague);
  } catch (error) {
    return res.status(500).json(error);
  }
};

В этом методе я отправляю firstTeam = 1 и secondTeam = 5. Это id из столовых команд.

Далее у меня есть ассоциированная модель событий:

...
  Event.associate = models => {
    Event.belongsTo(models.Team, { foreignKey: 'firstTeam', as: 'teamFirst' });
    Event.belongsTo(models.Team, { foreignKey: 'secondTeam', as: 'teamSecond' });
  };
...

И сотрудник модели команды:

...
  Team.associate = models => {
    Team.hasMany(models.Event, { foreignKey: 'eventId', as: 'event' });
  };
...

В таблице команд у меня есть:

+----+--------+----------------+------+------+----------+---------------------+---------------------+
| id | userId |      name      | logo | type | leagueId |      createdAt      |      updatedAt      |
+----+--------+----------------+------+------+----------+---------------------+---------------------+
|  1 |      1 | Arsenal Londyn | test |    1 |        1 | 2020-02-24 09:13:23 | 2020-02-24 09:13:23 |
|  2 |      1 | Chelsea Londyn | test |    1 |        1 | 2020-02-24 09:22:23 | 2020-02-24 09:22:23 |
+----+--------+----------------+------+------+----------+---------------------+---------------------+

Как я могу проверить, существует ли строка по teams.id = 5? Почему Sequelize не возвращает мне ошибку? В таблице teams у меня нет id = 5.

Я использую базу данных MySQL.

РЕДАКТИРОВАТЬ (26-02-2020):

Файл групповой миграции:

module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Teams', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER,
      },
      userId: {
        allowNull: false,
        type: Sequelize.INTEGER,
      },
      name: {
        allowNull: false,
        type: Sequelize.STRING,
        unique: true,
      },
      logo: {
        type: Sequelize.STRING,
      },
      type: {
        allowNull: false,
        type: Sequelize.INTEGER,
      },
      leagueId: {
        allowNull: false,
        type: Sequelize.INTEGER,
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Teams');
  },
};

Файл переноса события:

module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Events', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER,
      },
      userId: {
        type: Sequelize.INTEGER,
      },
      type: {
        allowNull: false,
        type: Sequelize.INTEGER,
      },
      leagueId: {
        allowNull: false,
        type: Sequelize.INTEGER,
      },
      firstTeam: {
        allowNull: false,
        type: Sequelize.INTEGER,
      },
      secondTeam: {
        type: Sequelize.INTEGER,
      },
      date: {
        allowNull: false,
        type: Sequelize.DATE,
      },
      place: {
        allowNull: false,
        type: Sequelize.STRING,
      },
      deleted: {
        type: Sequelize.BOOLEAN,
        defaultValue: false,
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Events');
  },
};

Файл модели команды:

module.exports = (sequelize, DataTypes) => {
  const Team = sequelize.define(
    'Team',
    {
      userId: DataTypes.INTEGER,
      name: DataTypes.STRING,
      logo: DataTypes.STRING,
      type: DataTypes.INTEGER,
      leagueId: DataTypes.INTEGER,
    },
    {},
  );
  Team.associate = models => {
    Team.hasMany(models.Event, { foreignKey: 'firstTeam', as: 'teamFirst' });
    Team.hasMany(models.Event, { foreignKey: 'secondTeam', as: 'teamSecond' });
  };
  return Team;
};

Файл модели события:

module.exports = (sequelize, DataTypes) => {
  const Event = sequelize.define(
    'Event',
    {
      userId: DataTypes.INTEGER,
      type: DataTypes.INTEGER,
      leagueId: DataTypes.INTEGER,
      firstTeam: DataTypes.INTEGER,
      secondTeam: DataTypes.INTEGER,
      date: DataTypes.DATE,
      place: DataTypes.STRING,
      deleted: DataTypes.BOOLEAN,
    },
    {},
  );
  Event.associate = models => {
    Event.belongsTo(models.Team, { foreignKey: 'firstTeam', as: 'teamFirst' });
    Event.belongsTo(models.Team, { foreignKey: 'secondTeam', as: 'teamSecond' });
  };
  return Event;
};
0
michal 24 Фев 2020 в 12:50

2 ответа

Лучший ответ

Я нашел решение. Я забыл добавить references. Например, в моем файле переноса событий я добавил:

...
firstTeam: {
    allowNull: false,
    type: Sequelize.INTEGER,
    references: {
        model: 'teams',
        key: 'id',
    },
},
...

Теперь, когда я пытаюсь добавить событие с temat, которого нет в базе данных, sequelize возвращает мне ошибку:

"sqlMessage": "Невозможно добавить или обновить дочернюю строку: внешний ключ ограничение не выполнено (football. events, CONSTRAINT events_ibfk_4 ЗАРУБЕЖНЫЙ КЛЮЧ (firstTeam) ССЫЛКИ teams (id)) ",

0
michal 4 Мар 2020 в 07:57

Вы не правильно определили ассоциации. Если бы вы правильно определили ограничения отношений, тогда сам запрос SQL возвратил бы ошибку.

Я не понял модель данных, которую вы описали в этом вопросе, но я могу дать вам подсказку для отладки кода. Вы можете просмотреть запросы, сгенерированные Sequelize, установив синхронизацию в true .

Кроме того, вы можете проверить, можете ли вы создать запрос, который вы ожидаете.

Я надеюсь, что это помогает!

Изменить. (03-03-2020)

Я проверил операторы создания, сформированные Sequelize для моделей Event и Team. Это следующие -

Executing (default): CREATE TABLE IF NOT EXISTS `teams` (`id` INTEGER NOT NULL auto_increment , `user_id` INTEGER, `name` VARCHAR(255), `logo` VARCHAR(255), `type` INTEGER, `league_id` INTEGER, `created_at` DATETIME NOT NULL, `updated_at` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): CREATE TABLE IF NOT EXISTS `events` (`id` INTEGER NOT NULL auto_increment , `user_id` INTEGER, `type` INTEGER, `league_id` INTEGER, `first_team` INTEGER, `second_team` INTEGER, `date` DATETIME, `place` VARCHAR(255), `deleted` TINYINT(1), `created_at` DATETIME NOT NULL, `updated_at` DATETIME NOT NULL, PRIMARY KEY (`id`), FOREIGN KEY (`first_team`) REFERENCES `teams` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE, FOREIGN KEY (`second_team`) REFERENCES `teams` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE) ENGINE=InnoDB;

Кажется, вы правильно определили ассоциации.

При добавлении событий, для которых нет команды, я получаю ответ:

{
    "isFulfilled": false,
    "isRejected": false
}

Я получаю сообщение об ошибке ограничения внешнего ключа на консоли следующим образом:

Unhandled rejection SequelizeForeignKeyConstraintError: (conn=320, no: 1452, SQLState: 23000) Cannot add or update a child row: a foreign key constraint fails (`nagios_logs`.`events`, CONSTRAINT `events_ibfk_1` FOREIGN KEY (`first_team`) REFERENCES `teams` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE)
sql: INSERT INTO `events` (`id`,`user_id`,`type`,`league_id`,`first_team`,`second_team`,`date`,`place`,`created_at`,`updated_at`) VALUES (DEFAULT,?,?,?,?,?,?,?,?,?); - parameters:[1,1,2,1,2,'2020-03-23 18:30:00.000','New york','2020-03-03 06:51:07.109','20...]

Я не могу воспроизвести проблему, которую вы описали в этом вопросе.

0
Soham Lawar 3 Мар 2020 в 06:54