AdonisJSのSQLクエリをデバッグする
AdonisJSのSQLクエリをデバッグする
2022/11/23

AdonisではORMを使ってDBへのアクセスを行うので、実際に発行されているSQLクエリがわからない。
そのため、N+1問題とかを見つけにくくなっている。

シンプルな宣言だったらクエリのイメージはつく

const project = await Project.query().where('id', id).first()

related, preloadなのリレーションも検索するとなると実際どういったクエリが動いているかが想像しにくい、、

const projects = await user
      .related('projects')
      .query()
      .whereNot('status', 'preview')
      .preload('items')
      .preload('image')

今回は裏で発行されているSQLクエリをログに出力できる設定を紹介します。
2パターンあって、すべてのクエリが出力と確認したいクエリだけを出力する方法があります。

AdonisのSQLクエリをログに出力

データベースの設定でデバッグを有効にする

DB設定でデータベースのデバッグをonにすると、上記で設定したEvent db:queryが発行されるようになる。

const databaseConfig: DatabaseConfig = {
  connections: {
    mysql: {
      debug: true,
    },
  }
}

SQLクエリをログに出力する設定をする

全てのクエリを出力する

AdonisJSの機能のひとつEventを使ってSQLクエリを検知してログ出力する

まずはEventのファイルを用意する。

$ node ace make:prldfile events
❯ Select the environment(s) in which you want to load this file · No items were selected

CREATE: start/events.ts

make:prldfileとはpreloadsと呼ばれる機能用のファイルを作成するコマンドで、preloadsはアプリケーション起動時に一度だけ読み込み実行されます。

.adonisrc.jsonに先程作成したファイルが追加されていると思います。

ここにEvent機能を使ってクエリを検知したらログを出力するコードを書きます。

import Event from '@ioc:Adonis/Core/Event'
import Logger from '@ioc:Adonis/Core/Logger'
import Database from '@ioc:Adonis/Lucid/Database'
import Application from '@ioc:Adonis/Core/Application'

Event.on('db:query', (query) => {
  if (Application.inProduction) {
    Logger.debug(query)
  } else {
    Database.prettyPrint(query)
  }
})

アプリを再起動するとコンソールにログが出力されます。

AdonisのSQLクエリをログに出力

特定のクエリのみを確認する

上記ですべてのクエリが確認できるようにはなるのですが、複雑なプログラミングになると一度で10個以上のクエリが動いたりと自分の確認したいクエリがどれなのかがわかりづらくなってしまうので、特定のクエリのみログを出力する方法も紹介します。

方法はシンプルで出力したいQueryBuilderに.debug(true)を追加するだけ。

Database
  .query()
  .select('*')
  .debug(true) // 👈

最初のconfigファイルで設定を忘れていなければログが出力されるかと思います。

以上になります。

この他にも、AdonisJS v5へのアップグレードで行ったことをまとめました。
なにか役に立てたら幸いです。