Symfoware

Symfowareについての考察blog

Node.js MySQLへのバルクインサートと、AUTO_INCREMENTで振られた値

Node.jsからMySQLに接続してみました。
Node.jsからMySQLに接続する

今回はバルクインサートを試してみます。


Nested arrays



https://www.npmjs.com/package/mysql
こちらをよく読んでみると、


Nested arrays are turned into grouped lists (for bulk inserts),
e.g. [['a', 'b'], ['c', 'd']] turns into ('a', 'b'), ('c', 'd')



なるほど、配列を渡せば目的は達成できそうです。
こんなプログラムを書いてみました。


  1. 'use strict'
  2. const mysql = require('mysql')
  3. // データベース接続
  4. const con = mysql.createConnection({
  5.     host     : '192.168.1.102',
  6.     user     : 'admin',
  7.     password : 'P@ssw0rd',
  8.     database : 'sample'
  9. })
  10. con.connect()
  11. // 登録用のデータ
  12. const values = [['データ1'], ['データ2'], ['データ3'], ['データ4']]
  13. // データの一括登録
  14. con.query('INSERT INTO test(value) VALUES ?', values, (err, results) => {
  15.     console.log(err)
  16.     console.log(results)
  17.     con.end()
  18. })



実行するとエラー


$ node index.js
{ Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''データ1'' at line 1
    at Query.Sequence._packetToError (/home/baranche/nodejs/mysql/node_modules/mysql/lib/protocol/sequences/Sequence.js:52:14)
    at Query.ErrorPacket (/home/baranche/nodejs/mysql/node_modules/mysql/lib/protocol/sequences/Query.js:77:18)
    at Protocol._parsePacket (/home/baranche/nodejs/mysql/node_modules/mysql/lib/protocol/Protocol.js:279:23)
    at Parser.write (/home/baranche/nodejs/mysql/node_modules/mysql/lib/protocol/Parser.js:76:12)
    at Protocol.write (/home/baranche/nodejs/mysql/node_modules/mysql/lib/protocol/Protocol.js:39:16)
    at Socket.<anonymous> (/home/baranche/nodejs/mysql/node_modules/mysql/lib/Connection.js:103:28)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    --------------------
    at Protocol._enqueue (/home/baranche/nodejs/mysql/node_modules/mysql/lib/protocol/Protocol.js:145:48)
    at Connection.query (/home/baranche/nodejs/mysql/node_modules/mysql/lib/Connection.js:208:25)
    at Object.<anonymous> (/home/baranche/nodejs/mysql/index.js:18:5)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)
    at startup (bootstrap_node.js:191:16)
code: 'ER_PARSE_ERROR',
errno: 1064,
sqlMessage: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'\'データ1\'\' at line 1',
sqlState: '42000',
index: 0,
sql: 'INSERT INTO test(value) VALUES \'データ1\'' }
undefined



何がまずいのかわからなかったのですが、以下のコードで動いてくれました。


  1. 'use strict'
  2. const mysql = require('mysql')
  3. // データベース接続
  4. const con = mysql.createConnection({
  5.     host     : '192.168.1.102',
  6.     user     : 'admin',
  7.     password : 'P@ssw0rd',
  8.     database : 'sample'
  9. })
  10. con.connect()
  11. // 登録用のデータ
  12. const values = [['データ1'], ['データ2'], ['データ3'], ['データ4']]
  13. // データの一括登録
  14. // リストを更にリストにする
  15. con.query('INSERT INTO test(value) VALUES ?', [values], (err, results) => {
  16.     console.log(err)
  17.     console.log(results)
  18.     con.end()
  19. })






バルクインサート時のAUTO_INCREMENT



バルクインサートした後、AUTO_INCREMENTで振られた番号をすぐに使用したい場合。
insertIdに、AUTO_INCREMENTで採番された最初の数値が入っています。

この数値から連番で番号が振られるため、
insertId + 登録した要素のインデックス
とすれば、各データの番号がわかります。


  1. 'use strict'
  2. const mysql = require('mysql')
  3. // データベース接続
  4. const con = mysql.createConnection({
  5.     host     : '192.168.1.102',
  6.     user     : 'admin',
  7.     password : 'P@ssw0rd',
  8.     database : 'sample'
  9. })
  10. con.connect()
  11. // 登録用のデータ
  12. const values = [['A'], ['B'], ['C'], ['D']]
  13. // データの一括登録
  14. // リストを更にリストにする
  15. con.query('INSERT INTO test(value) VALUES ?', [values], (err, results) => {
  16.     const firstid = results.insertId
  17.     con.end()
  18.     values.forEach((item, i) => {
  19.         console.log(item[0] + 'のidは' + (firstid + i))
  20.     })
  21. })



実行結果


$ node index.js
Aのidは9
Bのidは10
Cのidは11
Dのidは12



登録後のテーブルの内容


mysql> select * from test;
+----+--------------+
| id | value        |
+----+--------------+
| 1 | データ1     |
| 2 | データ2     |
| 3 | データ3     |
| 4 | データ4     |
| 5 | データ1     |
| 6 | データ2     |
| 7 | データ3     |
| 8 | データ4     |
| 9 | A            |
| 10 | B            |
| 11 | C            |
| 12 | D            |
+----+--------------+
12 rows in set (0.00 sec)



テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/07/01(日) 17:08:24|
  2. node.js
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Node.jsからMySQLに接続する

Node.jsからMySQLへの接続を試してみます。

npm



MySQLへの接続はこちらのライブラリを使用することにしました。
https://www.npmjs.com/package/mysql

npmでインストールします。


$ npm install mysql



接続サンプルはこんな感じになりました。


  1. 'use strict'
  2. const mysql = require('mysql')
  3. // データベース接続
  4. const con = mysql.createConnection({
  5.     host     : '192.168.1.102',
  6.     user     : 'admin',
  7.     password : 'P@ssw0rd',
  8.     database : 'sample'
  9. })
  10. con.connect()
  11. con.query('SELECT CURRENT_TIMESTAMP', (err, results) => {
  12.     console.log(results)
  13. })
  14. // 切断
  15. con.end()



実行結果


$ node index.js
[ RowDataPacket { CURRENT_TIMESTAMP: 2018-07-01T07:32:52.000Z } ]



ちゃんとデータベースに接続できたようです。



データの登録と更新、削除



データの登録などを試してみます。
サンプルとして、こんなテーブルを作成しておきました。


CREATE DATABASE sample;
USE sample;
CREATE TABLE test (
     id INT NOT NULL AUTO_INCREMENT,
     value text NOT NULL,
     PRIMARY KEY (id)
);




サンプルはこんな感じになりました。


  1. 'use strict'
  2. const mysql = require('mysql')
  3. // データベース接続
  4. const con = mysql.createConnection({
  5.     host     : '192.168.1.102',
  6.     user     : 'admin',
  7.     password : 'P@ssw0rd',
  8.     database : 'sample'
  9. })
  10. con.connect()
  11. // データの登録
  12. con.query('INSERT INTO test SET ?', {value:'登録テスト'}, (err, results) => {
  13.     console.log(results)
  14.     const insertId = results.insertId
  15.     con.query('SELECT * FROM test WHERE id = ?', [insertId], (err, results) => {
  16.         console.log(results)
  17.         con.query('DELETE FROM test WHERE id = ?', [insertId], (err, results) => {
  18.             console.log(results)
  19.             // 切断
  20.             con.end()
  21.         })
  22.     })
  23. })



AUTO_INCREMENT列に採番された値は、結果の「insertId」に格納されています。
SELECTでは、insertIdの番号をプレースフォルダを使用してクエリーに埋め込み検索しています。

実行結果


$ node index.js
OkPacket {
fieldCount: 0,
affectedRows: 1,
insertId: 6,
serverStatus: 2,
warningCount: 0,
message: '',
protocol41: true,
changedRows: 0 }
[ RowDataPacket { id: 6, value: '登録テスト' } ]
OkPacket {
fieldCount: 0,
affectedRows: 1,
insertId: 0,
serverStatus: 2,
warningCount: 0,
message: '',
protocol41: true,
changedRows: 0 }



いい感じです。

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/07/01(日) 16:45:34|
  2. node.js
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

node.js + Redisで一括処理(pipline, multi)

node.jsからRedisの操作を試しています。
node.js Redisに接続してデータの登録、取得、削除
node.js + Redisでリストの操作(rpush, lrange, ltrim)

複数のコマンドを実行するpipline処理について調べてみました。


multi



redis - a node.js redis client

他のライブラリだと「pipline」という名称がよく使用されるのですが、
このライブラリでは「multi」と表現しているようです。


  1. 'use strict'
  2. const redis = require('redis')
  3. // 接続情報
  4. const config = {
  5.     host: '127.0.0.1',
  6.     port: 6379
  7. }
  8. // 接続
  9. const client = redis.createClient(config)
  10. // 一括処理
  11. client.multi()
  12.     .rpush('key', 'value-1')
  13.     .rpush('key', 'value-2')
  14.     .set('hoge', 'piyo')
  15.     .lrange('key', 0, -1)
  16.     .get('hoge')
  17.     .exec((err, replies) => {
  18.         replies.forEach((item,i ) => {
  19.             console.log(`result:${i}`)
  20.             console.log(item)
  21.         })
  22.     })
  23. client.quit()



「exec」でそれまで貯めていたコマンドを一括実行。
結果は、実行順に配列に格納されます。

実行結果


$ node index.js
result:0
1
result:1
2
result:2
OK
result:3
[ 'value-1', 'value-2' ]
result:4
piyo



「pipline」というキーワードで探していたため、なかなかこの機能を
見つけられなかったのでメモ。


テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/06/28(木) 23:37:15|
  2. node.js
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

node.js + Redisでリストの操作(rpush, lrange, ltrim)

node.jsからRedisに接続してみました。
node.js Redisに接続してデータの登録、取得、削除

PHPで試したときと同様のリスト操作を行ってみます。
Redis + FuelPHP 1.8でリストの操作(rpush, lrange, ltrim)


rpushとlrange



rpushでリストにデータ登録。
lrangeで登録したデータを取得してみます。


  1. 'use strict'
  2. const redis = require('redis')
  3. // 接続情報
  4. const config = {
  5.     host: '127.0.0.1',
  6.     port: 6379
  7. }
  8. // 接続
  9. const client = redis.createClient(config)
  10. // データの登録
  11. for (let i = 1; i <= 20; i++) {
  12.     client.rpush('key', `value-${i}`)
  13. }
  14. // データの取得と表示
  15. client.lrange('key', 0, 10, (err, reply) => {
  16.     reply.forEach((item, i) => {
  17.         console.log(item)
  18.     })    
  19. })
  20. // データの削除
  21. client.del('key')
  22. // 切断
  23. client.quit()



実行結果


$ node index.js
value-1
value-2
value-3
value-4
value-5
value-6
value-7
value-8
value-9
value-10
value-11





rpushで一括登録



rpushは第二引数以降の値を登録してくれます。


  1. 'use strict'
  2. const redis = require('redis')
  3. // 接続情報
  4. const config = {
  5.     host: '127.0.0.1',
  6.     port: 6379
  7. }
  8. // 接続
  9. const client = redis.createClient(config)
  10. // データの登録
  11. client.rpush('key', `value-1`, `value-2`, `value-3`, `value-4`, `value-5`)
  12. // データの取得と表示
  13. client.lrange('key', 0, 10, (err, reply) => {
  14.     reply.forEach((item, i) => {
  15.         console.log(item)
  16.     })    
  17. })
  18. // データの削除
  19. client.del('key')
  20. // 切断
  21. client.quit()



実行結果


$ node index.js
value-1
value-2
value-3
value-4
value-5




リストを渡してもよしなに処理してくれます。


  1. 'use strict'
  2. const redis = require('redis')
  3. // 接続情報
  4. const config = {
  5.     host: '127.0.0.1',
  6.     port: 6379
  7. }
  8. // 接続
  9. const client = redis.createClient(config)
  10. let values = []
  11. for (let i = 1; i <= 20; i++) {
  12.     values.push(`value-list-${i}`)
  13. }
  14. // データの登録
  15. client.rpush('key', values)
  16. // データの取得と表示
  17. client.lrange('key', 0, 10, (err, reply) => {
  18.     reply.forEach((item, i) => {
  19.         console.log(item)
  20.     })    
  21. })
  22. // データの削除
  23. client.del('key')
  24. // 切断
  25. client.quit()



実行結果


$ node index.js
value-list-1
value-list-2
value-list-3
value-list-4
value-list-5
value-list-6
value-list-7
value-list-8
value-list-9
value-list-10
value-list-11





リストの削除(ltrim)



リストから指定件数読み出し、読み出した分を削除しつつ継続して読み込み...はこうなりました。


  1. 'use strict'
  2. const redis = require('redis')
  3. // 接続情報
  4. const config = {
  5.     host: '127.0.0.1',
  6.     port: 6379
  7. }
  8. // 接続
  9. const client = redis.createClient(config)
  10. let values = []
  11. for (let i = 1; i <= 25; i++) {
  12.     values.push(`value-${i}`)
  13. }
  14. // データの登録
  15. client.rpush('key', values)
  16. // リストが尽きるまで読み込み
  17. const read = () => {
  18.     client.lrange('key', 0, 10, (err, reply) => {
  19.         if (reply.length == 0) {
  20.             client.quit()
  21.             return
  22.         }
  23.         reply.forEach((item, i) => {
  24.             console.log(item)
  25.         })
  26.         client.ltrim('key', reply.length , -1)
  27.         read()
  28.     })
  29. }
  30. read()




実行結果


$ node index.js
value-1
value-2
value-3
value-4
value-5
value-6
value-7
value-8
value-9
value-10
value-11
value-12
value-13
value-14
value-15
value-16
value-17
value-18
value-19
value-20
value-21
value-22
value-23
value-24
value-25

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/06/28(木) 23:25:17|
  2. node.js
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

node.js Redisに接続してデータの登録、取得、削除

node.jsからRedisに接続して、データの登録などを試してみます。


redis



接続には、こちらを使用することにしました。
redis - a node.js redis client

npmでインストールします。


$ npm install redis





登録と取得、削除



データベースに接続し、getやsetを試してみます。

・index.js


  1. 'use strict'
  2. const redis = require('redis')
  3. // 接続情報
  4. const config = {
  5.     host: '127.0.0.1',
  6.     port: 6379
  7. }
  8. // 接続
  9. const client = redis.createClient(config)
  10. // データの登録
  11. client.set('key', 'value')
  12. // データの取得と表示
  13. client.get('key', (err, reply) => {
  14.     console.log(reply)
  15. })
  16. // データの削除
  17. client.del('key')
  18. // 削除されているか確認
  19. client.get('key', (err, reply) => {
  20.     console.log(reply)
  21. })
  22. // 切断
  23. client.quit()



実行結果


$ node index.js
value
null






データベースの切り替え



データベースの切り替えも試してみます。


  1. 'use strict'
  2. const redis = require('redis')
  3. // 接続情報
  4. const config = {
  5.     host: '127.0.0.1',
  6.     port: 6379
  7. }
  8. // 接続
  9. const client = redis.createClient(config)
  10. // データの登録
  11. client.set('key', 'value1')
  12. // データの取得と表示
  13. client.get('key', (err, reply) => {
  14.     console.log(reply)
  15. })
  16. // データベース切り替え
  17. client.select(1)
  18. // 登録と検索
  19. client.set('key', 'value2')
  20. client.get('key', (err, reply) => {
  21.     console.log(reply)
  22. })
  23. // 切断
  24. client.quit()



いい感じです。


$ node index.js
value1
value2




設定ファイルの「db」項目でも変更可能です。


  1. 'use strict'
  2. const redis = require('redis')
  3. // 接続情報
  4. const config = {
  5.     host: '127.0.0.1',
  6.     port: 6379,
  7.     db: 1 // db:1に接続
  8. }
  9. // 接続
  10. const client = redis.createClient(config)
  11. // データの取得と表示
  12. client.get('key', (err, reply) => {
  13.     console.log(reply)
  14. })
  15. // 切断
  16. client.quit()



実行結果


$ node index.js
value2


テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/06/28(木) 23:01:22|
  2. node.js
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
次のページ