2018-10-23に更新

Nuxt.js+Expressでとにかく簡単にORM

Nuxt.jsとExpressを使ってアプリケーションを作るとなると、やはりMySQL等を使うためにORMのライブラリが欲しくなります。Node.jsにはSequelizeというORMのライブラリがあり、それを使って簡単にデータベースを使うことが可能です。

趣旨

Sequelizeの使い方の説明は他のサイトの記事などがもっと参考になります。ただ、とりあえずすぐ簡単に使う、という趣旨の記事があまりなさそうだったのでそのあたりに重点を置いて書いてみます。

ちなみに下記で作ったプロジェクトの続きとして作っています。 Nuxt+Expressのプロジェクト作成で良さそうなのは?

インストール

インストールはマニュアル通りです。npmを使う場合はマニュアルを見てください。

Installation | Sequelize | The node.js ORM for PostgreSQL, MySQL, SQLite and MSSQL

// Using Yarn
$ yarn add sequelize

# And one of the following:
$ yarn add pg pg-hstore
$ yarn add mysql2
$ yarn add sqlite3
$ yarn add tedious // MSSQL

初期化

引き続き上記のマニュアルを見て初期化…ではなく、そこは飛ばして下記の通りにやっていきます。

Tutorial | Sequelize | The node.js ORM for PostgreSQL, MySQL, SQLite and MSSQL

どういうことかというと、最初のリンクの説明どおりに設定していかなくても、Sequelizeにはsequelize-cliというものもあり、それを使えばなんでもかんでもシェルでコマンド実行するだけで簡単にできてしまいます。

インストール

とりあえずはsequelize-cliをインストールします。(npmの場合はマニュアルどおりです)

グローバルにインストールしておけば実行時にパスの指定が必要なくなります。

yarn add sequelize-cli

初期化

下記コマンドで初期化します。

node_modules/.bin/sequelize init

これでなんか必要なファイルを全部作ってくれます。

config/config.jsonというファイルにデータベースへの接続情報設定がありますのでそちらに適宜入力していきます。とりあえず最初に試す時は直接入力してしまってOKです。

時間のある時にでも生成されたmodels/index.jsを見ればわかりますが、config.jsonにuse_env_variableの設定を入れたりすると環境変数から読み込んだりもできるので、コミットしたり本番環境を作ったりする場合はそのあたりが使えると思います。

モデルとマイグレーションファイルを作成する

ORMのため、マイグレーションファイルを作ってデータベースにテーブルを登録できるようにし、モデルを作ってアプリケーション上でデータを操作できるようにします。

これもコマンドで簡単に作成できます。下記は本家に書かれている例です。

node_modules/.bin/sequelize model:generate --name User --attributes firstName:string,lastName:string,email:string

これでマイグレーションファイルとモデルのファイルが作成されます。createdAt, updatedAtというタイムスタンプのカラムも自動的に追加されます。このあたりは--underscoredオプションを付けるとcreated_at, updated_atのようにスネークケースで作成できます。他のフレームワーク等との互換性を考えるのであれば指定しましょう。

マイグレーションを実行

node_modules/.bin/sequelize db:migrate

これで接続情報などが間違っていなければテーブルが作成されているはずです。

ちなみに僕はDBまわりだけdocker-composeを使って用意しています。(もちろんローカル等でデータベースが動いている場合には不要です)

version: '2'
volumes:
  mysql_data:
    driver: local
services:
  mysql:
    image: mysql:8.0
    volumes:
      - mysql_data:/var/lib/mysql
    ports:
      - 3308:3306
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "true"
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=mysql
      - PMA_USER=root
      - PMA_PASSWORD=
    ports:
      - 8102:80

よく分からない人はmysqlのバージョンを8ではなく5.6とか5.7にしてください。そうすればhttp://localhost:8102でphpmyadminも使えるので簡単にデータベースが作成できます。動いてすっきりしたあとにでもまた調べてバージョンを上げてみてください。(ヒント:mysql_native_password)

この場合接続設定はこんな感じです。

  "development": {
    "username": "root",
    "password": null,
    "database": "yourdatabse",
    "host": "127.0.0.1",
    "port": "3308",
    "dialect": "mysql"
  },

実際にデータを読み書き

まずはSequelizeの設定を読み込んで使えるようにします。モデルなどは自動的に読み込んでくれるのでこの1文だけでOKです。

const models = require("../models");

../modelsは生成されたmodelsフォルダの位置です。階層が違う場合は適宜書き換えてください。

ちなみにルーティングを別ファイルに分けている場合など、単にrequireしてもモデルがundefinedになっていることがありますので、その場合は最初にアプリケーションにmodelsを登録しておき、アクション内ではリクエストパラメータで取得すると良いです。

app.set("models", require("../models"));
router.post("/posts", async function(req, res, next) {
  const Post = req.app.get("models").Post;

書き込み

書き込み方法はいくつかあるので一例です。

models.User.build({
    first_name: "Hoge",
    last_name: "Fuga"
  })
  .save()

読み込み

こちらも1例です。plain: trueで取得すると単なるオブジェクトとして利用できるようになります。

router.get("/users", async function(req, res, next) {
  const users = await models.User.findAll();

  res.json(
    users.map(user => {
      return user.get({ plain: true });
    })
  );
});

例えばVueコンポーネント側で取得し

  async asyncData() {
    let { users } = await axios.get("/api/users");
    return { users };
  }

受け取ったら下記のような感じで表示できます。上記の様にasyncDataで取っている場合はサーバーサイドレンダリングされています。

      <div v-for="user in users" :key="user.id">
        {{ user.name }}
      </div>

まとめ

とりあえずsequelize-cliがあることでかなり初期設定を短縮できています。これがなかったら特にはじめての人とかは結構つまづく箇所が多いのではないかと思います。

他の言語の他のフレームワークと比べてもさほど使い勝手も変わらず良さそうな感じがしました。


dala00

Crieitの開発者です。 主にLAMPで開発しているWebエンジニアです(在宅)。大体10年程。 記事でわかりにくいところがあればDMで質問していただくか、案件発注してください。 業務依頼、同業種の方からのコンタクトなどお気軽にご連絡ください。 業務経験有:PHP, MySQL, Laravel5, CakePHP3, JavaScript, RoR 趣味:Elixir, Phoenix, Node, Nuxt, Express, Vue等色々

Crieitはαバージョンで開発中です。進捗は公式Twitterアカウントをフォローして確認してください。 興味がある方は是非記事の投稿もお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか
関連記事

コメント