- PostgreSQLでBULK INSERTしたい
- nodeモジュールのnode-postgresを使って接続する
- prepare statementを使ってやりたい
PostgreSQLへのデータアクセスをする際に、node-postgresモジュールを利用しています。
そのときに一括インサート(BULK INSERT)を行いたいのですが、prepare statementを使用したやり方がわからなかったので調べてみました。
- node-postgresモジュールを使ったバルクインサートのやり方
- prepare statementっぽく構文を記述する方法
PostgresSQLでやりたいバルクインサート
PostgreSQLでもバルクインサートは普通に書いて実行できます。
PostgresSQLでのバルクインサートの書き方
INSERT INTO table (id, name) VALUES (1, 'hoge'), (2, 'fuga'), (3, 'foo');
これをprepare statementを使ってVALUE句を書きたいのですが・・・
以下のMySQLと同じようなprepare statementの使い方ではエラーとなってしまいます。
MySQLのパターン
const sql = 'INSERT INTO table (id, name) VALUES ?';
const params =[[1, 'hoge'], [2, 'fuga'], [3, 'foo']];
await mysql.query(sql, [params]);
PostgresSQLでのバルクインサート解決方法
結論から言うと
PostgresSQLでprepare statementを使ってバルクインサートを行う方法は見つかりませんでした・・・
もしかしたらあるのかもしれませんが・・
pg-formatを使うことでprepare statementと似たような書き方が可能
その代わり、pg-formatと言うライブラリモジュールを使うことによって、prepare statementと似たような書き方が可能になりましたので、そのやり方を紹介します。
こちらのサイトにやり方が書いてありました。
実際にやってみるとこうなります。
pg-formatを使った代替案
const format = require('pg-format');
const params =[[1, 'hoge'], [2, 'fuga'], [3, 'foo']];
const sql = format('INSERT INTO table (id, name) VALUES %L, params)';
await pgClient.query(sql, [params]);
みて貰えばわかると思うのですが、pg-formatを使って先に宣言したparamsの配列をsql分に展開して1つのsqlを作成してます。
詳しくは上の参考サイトやpg-formatのドキュメントをみるとよくわかると思います。
実際にはprepare statementの動きはしませんので、SQLのパフォーマンス的には異なるで注意です。
また、SQLとして展開するので基本的には文字列扱いのSQLとなるようです。
PostgreSQLでバルクインサートまとめ
とりあえずpg-formatを使ってprepare statementではありませんが、似たようなコーティングができる方法を紹介しました。
SQLなので文字列として扱われることや、配列が多すぎるとSQLが長くなってしまったりと注意することはありますが、その辺を考慮して使う分には簡単にバルクインサートの実装ができると思います。
もし同じようにPostgreSQLでバルクインサートをしたくて困ってる人の参考になれば幸いです。
- PostgreSQL(node-postgres)でバルクインサートするにはprepare statementを使っては無理?
- pg-formatを使ってSQLにすれば同じようなコーディングが可能
- SQLを成形するので、型やSQL文字数などには注意して使う
どちらも入門書なので、自分に合わせた本を選べばいいと思います。
コメント