Как заранее избежать использования mysql / sqlstring в Node.js навалом INSERT? - PullRequest
1 голос
/ 23 апреля 2020

Я использую следующие модули узлов:

const mysql = require('mysql');
const SqlString = require('sqlstring');

Я читаю JSON из файлов и анализирую JSON во вложенный массив. Затем я передаю вложенный массив в массив MySQL INSERT.

. Это прекрасно работает для 25 из 26 файлов и загружает более 500 записей. Один файл содержит 21 JSON записей, и только следующая запись не выполняется:

[
    {
        "abstract": "... AWS Shared responsibility model:​ https://aws.amazon.com/compliance/shared-responsibility-model/; Enabling object-level logs in S3:​ ...",
        "title": "Defeating a Cloud Breach Part 1"
    }
]

Я выделил проблему в поле "abstract".

Я попытался экранировать значение " абстракция "перед загрузкой в ​​массив с использованием обоих connection.escape () и SqlString.escape () из модулей" mysql "и" sqlString "соответственно. Ни один из случаев не исправляет то, что вызывает сбой INSERT.

Сбой INSERT, возвращая «undefined» независимо от методов. Успешный INSERT возвращает что-то вроде:

OkPacket {
  fieldCount: 0,
  affectedRows: 4,
  insertId: 142,
  serverStatus: 2,
  warningCount: 0,
  message: '&Records: 4  Duplicates: 0  Warnings: 0',
  protocol41: true,
  changedRows: 0
}

Столбец "abstract" в таблице MySQL имеет тип "text", и есть много других записей, длина которых превышает запись проблемы выше.

SqlString - Когда я перебираю ключ / значения JSON, я пытался экранировать строку перед помещением во вложенный массив.

Пример: abstract = SqlString.escape (значение))

Я также пробовал весь оператор INSERT, поэтому:

var sql = "INSERT INTO tbl (abstract,title,url,key_word) VALUES ?";

sql = SqlString.format(sql, [dbVals]);

var query = client.query(sql, function(err, result) {
console.log(result);
});

Очевидно, что в поле выше "client" есть экземпляр "mysql" CONNECTIONS (именно поэтому я также попытался подать в суд на mysql .escape () и client.escape () вместо SqlString.escape ())

Но я получаю точно такой же результат и только в этой одной записи .

Я подтвердил, что проблема заключается в том, что я удалил запись, указанную выше, и установил значение abstract в пустую строку, а в ОБА этих экземпляров - основная масса Вставить успешно.

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

Спасибо.

РЕДАКТИРОВАТЬ: Дополнительная информация добавлена ​​в вопрос.

1 Ответ

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

Я подозреваю, что ваша проблема может быть связана с вашей схемой. Также сбивает с толку: одна часть вашего примера указывает на то, что вы пытаетесь вставить 4 значения (abstract,title,url,key_word), но ваша полезная нагрузка содержит только 2 поля - неясно, как это несоответствие или как обрабатываются значения по умолчанию / null на стороне БД.

При тестировании с примером полезной нагрузки, который вы предоставили, с использованием схемы наилучшего предположения, я не столкнулся с проблемой. Поскольку ваша полезная нагрузка включает только 2 поля, мое тестирование включает только эти поля. Примеры для каждого компонента ниже для сравнения с вашим собственным.

Не стесняйтесь делиться дополнительной информацией о вашей БД, схеме таблицы и полях, если у вас все еще возникают проблемы. charset вашей БД, таблицы и поля также могут быть полезны для изучения.

ДАННЫЕ БАЗЫ ДАННЫХ
MySQL v5.7.12

CREATE TABLE `tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `abstract` text,
  `title` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;

УЗЕЛ

// 
// other require items here as well depending on file location in project
// 
const mysql = require('mysql');

const db = mysql.createPool({
  connectionLimit: 10,
  host: process.env.DB_HOST || '127.0.0.1',
  user: process.env.DB_USER || 'local_user',
  password: process.env.DB_PASSWORD || 'local_password',
  database: process.env.DB_NAME || 'local_database',
  multipleStatements: true, 
  charset: 'utf8mb4' // necessary if you might need support for emoji characters
});

let entries = [
  {
    "abstract": "An easy one",
    "title": "Defeating a Cloud Breach Part 0"
  },
  {
    "abstract": "... AWS Shared responsibility model:​ https://aws.amazon.com/compliance/shared-responsibility-model/; Enabling object-level logs in S3:​ ...",
    "title": "Defeating a Cloud Breach Part 1"
  },
  {
    "abstract": "Another easy one",
    "title": "Defeating a Cloud Breach Part 2"
  }
]
let keys = Object.keys(entries[0]);
let values = entries.map( obj => keys.map( key => obj[key]));
let sql = 'INSERT INTO tbl (' + keys.join(',') + ') VALUES ?;';
db.query(sql, [values], function (error, results) {
  if (error) console.log(error.code);
  console.log(results);
});

РЕЗУЛЬТАТЫ

OkPacket {
  fieldCount: 0,
  affectedRows: 3,
  insertId: 1,
  serverStatus: 2,
  warningCount: 0,
  message: '&Records: 3  Duplicates: 0  Warnings: 0',
  protocol41: true,
  changedRows: 0
}

db screenshot

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...