Node.js | ExpressでPostgreSQLを使う
Node.jsからPostgreSQLを使う
データベースは多くのWebアプリケーションで重要になる。Node.jsでは標準機能だけでなく、追加パッケージを使ってデータベースへアクセスする。この記事では、Herokuが標準的に対応しているPostgreSQLを利用する。
まずローカル環境にPostgreSQLをインストールする。アプリケーションのテストやHerokuのPostgreSQLコマンドを使うためにも必要である。PostgreSQLのbinディレクトリをシステムのPathへ追加し、psqlなどのコマンドをターミナルから呼び出せるようにしておく。
C:\Program Files\PostgreSQL\x.x\bin
Node.jsアプリケーションのディレクトリで依存関係をインストールし、PostgreSQL用パッケージを追加する。
$ npm install
$ npm install pg
pgはNode.jsからPostgreSQLへアクセスするためのパッケージである。
Herokuを準備する
アプリケーションのディレクトリでHerokuへログインし、PostgreSQLアドオンを追加する。
$ heroku login
$ heroku addons:add heroku-postgresql:dev
アドオンが追加されたら、アプリケーションの標準データベースとしてpromoteする。
$ heroku pg:promote HEROKU_POSTGRESQL_NAME_URL
HerokuのPostgreSQLコンソールからテーブルを作成する。
$ heroku pg:psql
この例では、簡単なmydataテーブルを作成する。
create table mydata (
id serial primary key,
name char(50),
mail char(100),
memo char(255)
);
Heroku用のファイル
HerokuへデプロイするExpressアプリケーションには、アプリケーション情報と起動コマンドが必要になる。package.jsonにはexpress、pg、ejsなどの依存関係を記述する。
{
"name": "application-name",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "latest",
"pg": "latest",
"ejs": "*"
}
}
アプリケーションのルートにProcfileを作成する。
web: node app.js
app.jsでルーティングする
この例ではトップページのほか、入力フォーム用の/addと、POST処理用の/createを用意する。
var add = require("./routes/add");
var create = require("./routes/create");
app.use("/add", add);
app.use("/create", create);
テーブルのレコードを表示する
トップページではroutes/index.jsとviews/index.ejsを使う。pg.connectでPostgreSQLへ接続し、select * from mydataを実行する。rowイベントで行を集め、endイベントでテーブルを描画する。
var con = "tcp://user:password@host:port/database";
pg.connect(con, function(err, client) {
var query = client.query("select * from mydata;");
var rows = [];
query.on("row", function(row) {
rows.push(row);
});
query.on("end", function() {
response.render("index", { title: "Express", data: rows });
});
});
テンプレート側ではdataをループし、各レコードのname、mail、memoをテーブルに表示する。
SQLクエリを実行する
データベースアクセスは、接続してからclient.queryを呼び出す形が基本である。
var query = client.query("select * from mydata;");
queryはQueryオブジェクトを返す。処理は非同期で行われるため、SELECT結果の行が直接戻り値として返るわけではない。検索結果、完了、エラーはrow、end、errorイベントで扱う。
レコードを追加する
追加ページはadd.ejs、add.js、create.jsで構成する。フォームはname、mail、memoを/createへ送信する。
<form method="post" action="/create">
<input type="text" name="name">
<input type="text" name="mail">
<input type="text" name="memo">
<input type="submit">
</form>
POSTハンドラではrequest.bodyから値を読み、INSERT文を実行し、完了後にトップページへリダイレクトする。
var qstr = "insert into mydata (name,mail,memo) values($1, $2, $3);";
var query = client.query(qstr, [name_str, mail_str, memo_str]);
query.on("end", function() {
response.redirect("/");
});
$1、$2、$3のプレースホルダには、第2引数の配列の値が順に渡される。このパターンを理解しておけば、データベースへ接続し、SQLをqueryで実行し、イベントで結果を処理するという流れで、基本的なデータベース操作を実装できる。