Sequelizeやexpressでハマったこととか
わざわざ1つの記事にするまでもなさそうなことをメモする。
Sequelize.jsの話
belongsToとhasManyの違い
sql - belongsTo vs hasMany in Sequelize.js - Stack Overflow
公式ページにも書いてあった気がする。
例えば、Album.belongsTo(Artist)
と書くとalbum.getArtist()
のようにアクセスできる。
逆に、Artist.hasMany(Album)
と書くとartist.getAlbums()
のようにアクセスできる。
つまり、1つを書いただけだと、片方向のアクセスしかできない。
PostgreSQLでテーブル名やカラム名をダブルクオーテーションで囲わないと見つからないというエラーになる
Sequelizeはテーブル名やカラム名をcamel caseで作るが、PostgreSQLのSQLを直に書くときはこれらの識別子をダブルクオーテーションで囲わないと全て小文字に自動的に変換されてしまう。 SQLを直で書くときは、すべてダブルクオーテーションで囲んで書けば解決。
many to manyのthrough tableが生成されない
各モデルごとにUser.sync()
とだけやっていたのが原因。
sequelize.sync()
を実行しないといけない。
Sequelizeでサブクエリの結果が入るはずのカラムがモデルのインスタンスの変数から取得できない
要するに、普通はuser.userName
のように取得できるはずが、もともとモデルに無いカラムでは取得できないということ。
user.getValue('追加したカラム名')
としたらいけた。
TypeScriptでモデルを定義したらTypeError: Class constructor Model cannot be invoked without 'new
ビルド時にクラスが関数に変換されるために発生するエラー。
@babel/preset-env
のtargets
は"node": "current"
になっているのに発生した。
結局、tsconfig.json
でのコンパイルターゲットがes5になっていたのが原因だった。es6にしたら治った。
{ "compilerOptions": { "target": "es6", ...
node.jsやexpressなど
Cannot find module '@babel/core', Cannot find module 'babel-preset-env'
古い情報と新しい情報をごっちゃにしてやっているとどこかでこのエラーが起きた。
新しいのは@babel/core
や@babel/preset-env
なので、そっちをちゃんとインストールして設定する。
Error: ENOSPC: System limit for number of file watchers reached, watch ' ... '
ファイルシステムのfile watcherの上限に達したということらしい。
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
で治った。
Jestでのテストでopen handle potentially keeping Jest from exitingというエラー
まず、expressサーバはテストのときはlistenしてはいけない。
javascript - Jest detects open handle with Express app - Stack Overflow
なので、例えばまず/app.js
に共通の処理を書き、
const express = require('express'); const app = express(); app.use('/api', ... module.exports = app
本番で起動するserver.js
では以下のようにapp.js
を読み込む。
const app = require('./app.js') app.listen(3000, () => console.log(`Listening on port: ${PORT}`))
そして、テストを実行するtest.js
ではapp.js
を読み込む。
const app = require('./app.js') describe('test block', () => { ...
もう1点、テストのときは最後にsequelizeのデータベースをcloseする必要がある。
// 他のモジュールで, ``export const database = new Sequelize( ...``としたやつ afterAll(async () => { await database.close(); })
それ以外にもasyncでテストを書くとうまく動かないみたいな報告があるが、自分の場合には該当しないようだった。
Asynchronous beforeEach / beforeAll? · Issue #1256 · facebook/jest · GitHub
(ポエム) SequelizeなどORMつらい
ちょっと複雑なクエリを書こうとすると、書き方を調べないといけないし、生成されるSQLもわかりにくくなって辛くなってくる。
結局、ORMのメリットは単純なクエリのオブジェクトへのマッピングが簡単にできることであって、やっぱり複雑なクエリを書いたりパフォーマンスを最適化したりするのには向いていないという話を聞いて納得した。