Проблема Node.js с Oracle-узлом executeMany - PullRequest
0 голосов
/ 10 января 2019

Я написал небольшой скрипт Node для чтения записей из таблицы базы данных Oracle, вызова внешнего Web-сервиса, который выполняет преобразование, и затем вставки результатов в другую таблицу. Поскольку мне нужно повторить тот же процесс для более чем 70 миллионов записей, я выбираю 10K строк за раз и выполняю вставку с помощью executeMany из Oracle-узла.

Вот код:

let insertQuery = `INSERT INTO ${start_table}_TOKEN_MASK (${id_field1}, ${id_field2}, TOKEN, CARD_NUMBER_MASK, CARD_NUMBER) VALUES (:id1, :id2, :token, :mask, :cardNumber)`;

function process_chunk() {

        counter++;

        // SELECT CARDS
        connection.execute(`SELECT 
                                ${start_table}.${id_field1},
                                ${start_table}.${id_field2},
                                ${start_table}.${card_field} 
                            FROM ${start_table}
                            LEFT JOIN ${start_table}_TOKEN_MASK ON ${start_table}.${id_field1} = ${start_table}_TOKEN_MASK.${id_field1}
                            WHERE TOKEN IS NULL AND ROWNUM <= ${max_per_run}`).then(async (res) => {

            if (res.rows.length <= 0) {

                console.log(`All done.`);
                console.timeEnd('mapping');
                connection.close();
                process.exit(0);

            }

            console.log(`Fetched ${res.rows.length} rows.`);

            var binds = [];

            try{

                console.log(`Starting tokenization...`);

                await Promise.map(res.rows, async (row) => {

                    const mask = `${row[2].toString().substring(0,4)}.${row[2].toString().substring(4,6)}${'X'.repeat(2)}.${'X'.repeat(4)}.${row[2].toString().substring(row[2].toString().length - 4)}`;

                    const token = await Tokenize(row[2]);

                    binds.push([row[0], row[1], token, mask, row[2]]);

                }, {concurrency: 150}).then(async () => {

                        // Send chunk to DB
                        console.log(`Sending to DB...`);

                        // Prevent failure on insertmany, dividing inserts into multiple transactions
                        var chunks = splitArray(binds, 5000);

                        await Promise.map(chunks, async (chunk) => {

                            const insertResult = await connection.executeMany(insertQuery, chunk, { autoCommit: true });
                            console.log(`Inserted ${insertResult.rowsAffected} rows. Commit.`);

                        }, {concurrency: 1}).then(() => {

                            console.log(`Chunk ${counter} tokenized.`);
                            process_chunk();

                        });

                });

            }
            catch(err){

                console.error(err);
                process.exit(1);

            }

        }).catch(err => {
            console.error(err);
        });

}

В конце процесса я вижу, что в новой таблице (где вставки были сделаны) есть записи, но каждый кортеж смешан, например:

ID_FIELD1, ID_FIELD2, TOKEN, CARD_NUMBER_MASK, CARD_NUMBER
1          2          1234   456789            458755
2          3          1235   456790            458789

Что показывает, что связки так или иначе "смешиваются" либо вставкой, либо драйвером оракула. ​​

Есть идеи, что может произойти?

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