Sequelize とは
Node.js 用の ORM です。
Sequelize で既存の DB を操作する
すでに作成済みの DB を Sequelize で操作します。以下の例では既存の DB は Rails で作られたものを用いますが、Rails で作られたものである必要はありません。
ポイント
ポイントは以下の点になるかなと思います。なお、もっといい方法がありそうなので、あくまで私が触れた範囲ということでお願いします。
1. Promise で書く
公式ドキュメントには断片的にサンプルコードが書いてありますが、Promise で書かないと正しく DB への操作ができません。具体的にどう書くかは後述します。
2. カラムを逐一定義する
ActiveRecord を用いて既存の DB を操作する場合は、モデル名を設定して継承するだけでよしなにやってくれますが、Sequelize の場合は逐一カラムを定義する必要があります*1。
ただ、全てのカラムを定義する必要はなく、用いるカラムを定義すればよいです。
具体的なコード
公式ドキュメントほぼそのままですが、具体的なコードはたとえば以下のようになります。DB には PostgreSQL を用いており、予め pg
と pg-hstore
と sequelize
は npm または yarn でインストール済みとします。
const Sequelize = require('sequelize'); const sequelize = new Sequelize( 'foo_bar', 'DB_USERNAME', 'DB_PASSWORD', { host: 'DB_HOSTNAME', dialect: 'postgres', } ); const Model = Sequelize.Model; class FooBar extends Model {} const { Op } = require('sequelize'); (async () => { await FooBar.init( { hogeFuga: { type: Sequelize.STRING, field: 'hoge_fuga' }, createdAt: { type: Sequelize.DATE, field: 'created_at' }, updatedAt: { type: Sequelize.DATE, field: 'updated_at' } }, { modelName: 'Foobar', tableName: 'foo_bar', sequelize } ); const sqlCountResult = await FooBar.count({ where: { id: { [Op.gt]: 100 } } }); console.log(sqlCountResult); const sqlWhereResult = await FooBar.findAll({ where: { id: 100 } }); console.log(sqlWhereResult[0].hogeFuga); })();
具体的なコードを実行した結果
上記のコードを実行すると、次の条件の内容が得られます。async
と await
を使って実行しています。
- DB の接続情報として次の通りに設定されます
- ホスト名:
DB_HOSTNAME
- ユーザ名:
DB_USERNAME
- パスワード:
DB_PASSWORD
- ホスト名:
- 対象テーブル
foo_bar
- 対象カラム
hoge_fuga
created_at
updated_at
sqlCountResult
に代入される内容は、foo_bar
にあるレコード数sqlWhereResult
に代入される内容は、foo_bar
にあるレコードの中でid
が100
のレコードの、hoge_fuga
カラムの内容- Sequelize に限った話ではないですが、
WHERE
で返ってくるレコードは複数(配列)であることに注意です
- Sequelize に限った話ではないですが、
created_at
とupdated_at
は余計な定義に思えるかもしれませんが、これを定義しておかないとエラーになります- 詳しくは公式ドキュメントのTimestampsの項目をご覧ください
DB上のテーブル名やカラム名は一般にスネークケースだと思いますが、DB の定義の中でそれらをキャメルケースに定義し直して、その命名を用いて JavaScript のコード上で扱っています。
備考
Node.js で ORM を使う場合はフレームワークで使うことがほとんど(?)なので、既存の DB を扱うことはないのかなと思います。フロントエンドではもちろん使うことはありませんし*2、そうでなくても API 経由で取得するのが今風かなと思います。