はじめに
以前にも似たような記事(※)を書いたが、より汎用性のありそうなコードを書く機会があったので、本記事にまとめておく。
おそらく、非同期とかトランザクションとかも考慮しているコードになっているはず…
※【Node.js+Express+PostgreSQL】ExpressにPostgreSQLを導入
環境
- node 10.15
- express 4.17
- pg 7.12
サンプルコード
command
npm install --save pg
index.js
constexpress=require("express");constpg=require("pg");constapp=express();constport=3000;app.listen(port,()=>{console.log(`Start server port: ${port}`);});constpool=newpg.pool({host:"hoge",database:"hogehoge",user:"hogehogehoge",port:5432,password:"hogehogehogehoge"});app.post("/register",(req,res)=>{constid=req.body.post_id;(async()=>{constclient=pool.connect();try{awaitclient.query("BEGIN");letresult=awaitclient.query("SELECT name FROM users WHERE id = $1",[id]);constuser_name=result.rows[0];client.query("INSERT INTO teams (member) VALUES ($1)",[user_name]);awaitclient.query("COMMIT");res.json({msg:"Successfully insert data!"});}catch{awaitclient.query("ROLLBACK");throwerr}finally{client.release();}})().catch(err=>{console.log(err.stack);res.json({msg:"Fail to insert data"});});});
解説
まず、クライアントから送られてきたpost_id
をもとに、users
テーブルからname
を検索。
次に、そのname
をteams
テーブルのmember
列に保存。
以上が実現したい処理の流れ。
const pool = new pg.pool{ ... }
の部分で、DB接続情報の設定。- Node.jsのDBアクセスは非同期推奨なので、
(async () => { ... })
とする。 const client = await pool.connect();
で同期的にDBに接続。- 読みやすさ重視で
try{ } catch{ } finally{ }
- 処理順がわからなかったが、ここが参考になった。
- トランザクションは、
BEGIN
で始まり、COMMIT
またはROLLBACK
で終わる。await client.query("BEGIN"); ... await client.query("COMMIT");
の場合、これらに囲まれている範囲のSQL文は、正常にデータベースに反映される。await client.query("BEGIN"); ... await client.query("ROLLBACK");
の場合、これらに囲まれている範囲のSQL文は、破棄されてデータベースには反映されない。- つまり、上記のサンプルコードのように、正常時には
COMMIT
で終わるように、エラー時にはROLLBACK
で終わるように書けばよい。
client.release();
は、DB接続を切るみたいな認識(要確認)
おわりに
取り急ぎ、メモとして残したので、抜け漏れなどあるかと。
見つけ次第、随時修正します。