Дублирующая запись '0-0' для ключа 'local_part' - PullRequest
0 голосов
/ 26 апреля 2020

Я делаю простой API для GET, POST, DELETE, UPDATE. Get работает хорошо, но у меня проблема с методом POST.

Когда я пытаюсь опубликовать некоторые данные, я получаю сообщение об ошибке:

    error:  Error: ER_DUP_ENTRY: Duplicate entry '0-0' for key 'local_part'
    at Query.Sequence._packetToError (D:\crud\nodejs-express-mysql-master\node_modules\mysql\lib\protocol\sequences\Sequence.js:47:14)
    at Query.ErrorPacket (D:\crud\nodejs-express-mysql-master\node_modules\mysql\lib\protocol\sequences\Query.js:79:18)
    at Protocol._parsePacket (D:\crud\nodejs-express-mysql-master\node_modules\mysql\lib\protocol\Protocol.js:291:23)
    at Parser._parsePacket (D:\crud\nodejs-express-mysql-master\node_modules\mysql\lib\protocol\Parser.js:433:10)
    at Parser.write (D:\crud\nodejs-express-mysql-master\node_modules\mysql\lib\protocol\Parser.js:43:10)
    at Protocol.write (D:\crud\nodejs-express-mysql-master\node_modules\mysql\lib\protocol\Protocol.js:38:16)
    at Socket.<anonymous> (D:\crud\nodejs-express-mysql-master\node_modules\mysql\lib\Connection.js:88:28)
    at Socket.<anonymous> (D:\crud\nodejs-express-mysql-master\node_modules\mysql\lib\Connection.js:526:10)
    at Socket.emit (events.js:210:5)
    at addChunk (_stream_readable.js:308:12)
    --------------------
    at Pool.query (D:\crud\nodejs-express-mysql-master\node_modules\mysql\lib\Pool.js:199:23)
    at Function.Alias.create (D:\crud\nodejs-express-mysql-master\app\models\customer.model.js:12:7)
    at exports.create (D:\crud\nodejs-express-mysql-master\app\controllers\customer.controller.js:20:9)
    at Layer.handle [as handle_request] (D:\crud\nodejs-express-mysql-master\node_modules\express\lib\router\layer.js:95:5)
    at next (D:\crud\nodejs-express-mysql-master\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (D:\crud\nodejs-express-mysql-master\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (D:\crud\nodejs-express-mysql-master\node_modules\express\lib\router\layer.js:95:5)
    at D:\crud\nodejs-express-mysql-master\node_modules\express\lib\router\index.js:281:22
    at Function.process_params (D:\crud\nodejs-express-mysql-master\node_modules\express\lib\router\index.js:335:12)
    at next (D:\crud\nodejs-express-mysql-master\node_modules\express\lib\router\index.js:275:10) {
  code: 'ER_DUP_ENTRY',
  errno: 1062,
  sqlMessage: "Duplicate entry '0-0' for key 'local_part'",
  sqlState: '23000',
  index: 0,
  sql: "INSERT INTO aliases (local_part, domain, recipients) VALUES (`local_part` = 'team', `domain` = 'exmple.ag', `recipients` = 'tete@o2.pl')"
}

Моя модель:

const Alias = function(aliases) {
  this.local_part = aliases.local_part;
  this.domain = aliases.domain;
  this.recipients = aliases.recipients;
};


Alias.create = (newAlias, result) => {
  sql.query(`INSERT INTO aliases (local_part, domain, recipients) VALUES (?)`,newAlias, (err, res) => {
    if (err) {
      console.log("error: ", err);
      result(err, null);
      return;
    }
    console.log("created alias: ", { nr: res.insertNr, ...newAlias });
    result(null, { nr: res.insertNr, ...newAlias });
  });
};

и есть мой контроллер

    exports.create = (req, res) => {
  if (!req.body) {
    res.status(400).send({
      message: "Content can not be empty!"
    });
  }

  // Create a Alias
  const aliases = new Alias({
    local_part: req.body.local_part,
    domain: req.body.domain,
    recipients: req.body.recipients
  });

  // Save Alias in the database
  Alias.create(aliases, (err, data) => {
    if (err)
      res.status(500).send({
        message:
          err.message || "Some error occurred while creating the Alias."
      });
    else res.send(data);
  });
};

Это старая БД / таблица, созданная не мной. Я ничего не могу изменить в этой таблице. Кроме того, вместо ID NR

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

Есть структура таблицы:

-- Table structure for table `aliases`
--

CREATE TABLE `aliases` (
  `nr` int(11) NOT NULL,
  `local_part` varchar(64) NOT NULL DEFAULT '',
  `domain` varchar(128) NOT NULL DEFAULT 'example.pl',
  `recipients` text
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- Indexes for table `aliases`
--
ALTER TABLE `aliases`
  ADD PRIMARY KEY (`nr`),
  ADD UNIQUE KEY `local_part` (`local_part`,`domain`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `aliases`
--
ALTER TABLE `aliases`
  MODIFY `nr` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2177;
COMMIT;

Я думаю, что есть проблема

ДОБАВИТЬ УНИКАЛЬНЫЙ КЛЮЧ local_part (local_part, domain);

но я не представляю, как я могу решить эту проблему в node.js

1 Ответ

1 голос
/ 26 апреля 2020

Ваш код для вставки данных

sql.query(`INSERT INTO aliases (local_part, domain, recipients) VALUES (?)`,
     newAlias, (err, res) => {

неверен. Использование вашего массива напрямую переводит в

INSERT INTO aliases (local_part, domain, recipients) 
VALUES (`local_part` = 'team', `domain` = 'exmple.ag', `recipients` = 'tete@o2.pl')

. Это не вставляет значение team в столбец local_part, а вставляет результат сравнения local_part = 'team' в столбец local_part. Это должно быть null, но из-за вашего режима sql это, кажется, дает вам 0. То же самое для других столбцов, поэтому вы в конечном итоге вставляете (0,0,0) в вашу таблицу. Что не удается во второй раз из-за уникального ключа, жалуясь, что (0,0) уже существует.

Вы можете использовать синтаксис set , где этот массив будет работать,

INSERT INTO aliases SET `local_part` = 'team', ...

, изменив код на

sql.query(`INSERT INTO aliases SET ?`, newAlias, (err, res) => {

или вы можете (или, скорее, должны) явно передать параметры, например,

sql.query(`INSERT INTO aliases (local_part, domain, recipients) VALUES (?,?,?)`,
     [newAlias.local_part, newAlias.domain, newAlias.recipients], (err, res) => {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...