ExpressにSequelizeを導入し、PostgreSQLを使用する
- 目的
目的
前回のExpressに、PostgreSQL + Sequelizeでmodel層の作成
PostgreSQLのインストール
普段はmysqlを使っているのでとりあえずHomebrewでPostgreSQLをmacにインストール。
brew install postgresql
やった方がいいであろうこと(僕はやってません)
- パスを通すこと
export PGDATA=/usr/local/var/postgres
PostgreSQLを起動・停止する際に「-D」オプションを渡す必要がなくなるので、やっておいた方がいいかもしれません。
- TIPS : postgresqlのローカルパス
/usr/local/var/postgres
PostgreSQLの簡易的な使い方
サーバー起動
pg_ctl start -D /usr/local/var/portgres
サーバー停止
pg_ctl stop -D /usr/local/var/postgres
データベース接続
psql -d [db_name]
別データベースに接続
\connect [db_name]
テーブル定義を確認
\d [table_name]
テーブル一覧を表示
\z
PostgresSQLから切断
\q
PostgreSQLに事前準備
PostgreSQLにデータベース作成
createdb express_sample
PostgreSQLにてユーザ作成
create user root
PostgreSQLユーザに権限付与
GRANT SELECT, UPDATE, INSERT, DELETE ON express_sample TO root;
PostgreSQLユーザー指定データベースアクセス
psql -d express_sample -Uroot
PostgreSQL, Sequelizeをpackage.jsonに書き込む
npm i -S sequelize npm i -S pg
オプション「-S」は-save(package.json)に書き込むの略。
ちなみに「i」はinstallの略。
sequelize-cliをインストール
npm install -g sequelize-cli
コマンドラインから sequelize のmigrationを実行できる
sequelize init Sequelize CLI [Node: 8.6.0, CLI: 3.0.0, ORM: 4.19.0] WARNING: This version of Sequelize CLI is not fully compatible with Sequelize v4. https://github.com/sequelize/cli#sequelize-support Created "config/config.json" Successfully created models folder at "/User/express_test/sampleapp/models". Successfully created migrations folder at "/Users/express_test/sampleapp/migrations". Successfully created seeders folder at "/Users/express_test/sampleapp/seeders".
Warningが出てる。
内容としては、「このバージョンのSequelize CLIは、Sequelize v4と完全に互換性がありません。」とのことみたい。
とりあえず無視して継続。
Expressのsequlizeのconfig設定(DB接続周り)
{ "development": { "username": "root", "password": "xxx", "database": "express_sample", "host": "127.0.0.1", "dialect": "postgres" }, "test": { "username": "root", "password": "xxx", "database": "express_sample", "host": "127.0.0.1", "dialect": "postgres" }, "production": { "username": "root", "password": "xxx", "database": "express_sample", "host": "127.0.0.1", "dialect": "postgres" } }
Sequelizeを利用したmvcの構築
movieテーブルを作成する
イメージ
youtubeの動画を登録するテーブルテーブル
カラム名 | 型 | 備考 |
---|---|---|
id | auto_increment | |
title | varchar | |
video_id | varchar | |
upload_date | date | yyyy-mm-dd |
tag | integer | 将来tagテーブルを作成する |
is_delete | boolean |
└ 「tag」はtag_idとかに名称を変更するべきかな。
Sequelizeにて上記テーブルのmodelを作成する
sequelize model:create --name movie --underscored --attributes title:string,video_id:string,tag:integer,upload_date:date,is_delete:boolean
オプションを設定しない場合は、自動的にid, createdAt, updatedAtが作成される。
もし、キャメルケースでcreatedAt等作成されるのがいやなら、「--underscored」オプションを追加してあげるとよい。スネークケースの「created_at」と命名される。
生成されたmigrationファイル(default値を設定)
'use strict'; module.exports = { up: (queryInterface, Sequelize) => { return queryInterface.createTable('movies', { id: { allowNull: false, autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER }, title: { type: Sequelize.STRING }, video_id: { type: Sequelize.STRING, unique: true }, tag: { type: Sequelize.INTEGER }, upload_date: { type: Sequelize.DATE }, is_delete: { type: Sequelize.BOOLEAN, defaultValue: false }, created_at: { allowNull: false, type: Sequelize.DATE }, updated_at: { allowNull: false, type: Sequelize.DATE } }); }, down: (queryInterface, Sequelize) => { return queryInterface.dropTable('movies'); } };
└ TODO : video_idはnotNull制約が必要やったなぁ…。
db migration実行 テーブル作成
sequelize db:migrate
アプリ側のCRUDを実装する前に先にテストデータをインサート
INSERT INTO movies (title, video_id, tag, upload_date, is_delete, created_at, updated_at) VALUES ('xxx', 'xxx1', 1, '2014-5-18', false, now(), now()), ('xxx', 'xxx2', 1, '2014-5-19', false, now(), now()), ('xxx', 'xxx3', 1, '2014-5-20', false, now(), now()), ('xxx', 'xxx4', 1, '2014-5-21', false, now(), now()), ('xxx', 'xxx5', 1, '2014-5-22', false, now(), now());
select実装
routes/index.js
const models = require('../models'); router.get('/', function(req, res, next) { models.movie.findAll().then(function(results) { res.render('index', {movies: results}); }); });
views/index.jade
each movie in movies .movie img(src='http://i.ytimg.com/vi/#{movie.video_id}/default.jpg') p.day #{movie.upload_date} a.links(href='https://youtu.be/#{movie.video_id}') p ##{movie.id} #{movie.title}アップロードしました。
使用法の所感
わかった。
Controllerにmodel層を読み込ませて、models.xxxで呼び出し。その処理が終わったら(then)コールバックで変数名を新たに付けて受け渡しも可能。
その処理で得た結果の名前を便宜的に使用することが可能。