1
0

[プラグイン]kyselyのマイグレーションを拡張した

Posted at

kysely とは

Typescript のクエリビルダーです。
手前味噌ですが去年紹介記事を書いています。

上の記事の時点ではPostgreSQL, MySQL, SQLiteが使えてましたがSQLServerも増えているみたいです。

本家のドキュメント(トップページ)はこちら

kysely におけるマイグレーション

マイグレーションファイルの書き方は knex とよく似ていますが、「マイグレーションの実行」部分を自分で書く必要があります。
その分、自由度が高いともいえますが、少し面倒です。

マイグレーションでほしい機能を自作する

手前味噌その2ですが、 kysely 系 npm パッケージをつくっています。
主に PostgreSQL に特化した追加機能を実装しています。
現在の最新バージョンは 0.2.4 です。

上の記事の時点では 0.1台でしたが、マイグレーション関係の機能を追加して 0.2 にしてみました。(バージョンのつけかた合ってる?)
また、 Node.js と Deno で一部ソースを共有できなさそうだったので、 Node.js オンリーの対応です。

マイグレーション実行

個々のプロジェクトでマイグレーション実行を書かなくて済むよう、コマンド化しました。
まず、接続先の情報などを記載する設定ファイルを作成します。

config.ts
import type { UtilConfig } from 'kysely-extends-pg-query';

const config: UtilConfig = {
  database: 'test01',
  host: 'localhost',
  port: 5432,
  ssl: undefined,
  owner: {
    user: 'test_01',
    password: 'pwd',
  },
  migrate: 'migrate',
  dryMigrateOutput: undefined,
  superUser: {
    user: 'postgres',
    password: 'postgres',
    database: 'postgres',
  },
  verbose: true,
  createDbOptions: undefined,
};

export default config;

下の表に、それぞれのフィールドの概要を記載しておきます。

フィールド 記載内容
database 接続先データベース名
host 接続先ホスト名/IPアドレス(未指定時localhost)
port 接続先ポート番号(未指定時5432)
ssl SSLモード(未指定時undefined=暗号化なし)
owner.user データベース所有者ロール名
owner.password データベース所有者パスワード
migrate マイグレーションファイルのあるフォルダパス
dryMigrateOutput dry runしたときの出力先ファイル(未指定時undefined=コンソールに出力)
superUser.xxx データベース作成時に利用するスーパーユーザー(DB・role作成権のあるユーザー)の情報(未指定時undefined=DB作成できない)
verbose true=たくさんログを出力する(未指定時false)
createDbOptions データベース作成時のオプション、encodinglocale

package.json で scripts 内に以下を書けば npm run migrate:latest で最新に、 npm run migrate:down でひとつ前に戻ります。
また、データベースの作成もnpm run migrate:initで可能です。(設定ファイルにてsuperUserの項目を指定する必要がある)

    "migrate:init": "kysely-extends-pg-query --mode migrate-init --config config.ts",
    "migrate:latest": "kysely-extends-pg-query --mode migrate-latest --config config.ts",
    "migrate:down": "kysely-extends-pg-query --mode migrate-down --config config.ts"

また、これらに追加してマイグレーションのdry run、すなわち実行するSQLを表示するだけで発行はしないモードも追加しました。
仕組みとしてはPgPool互換のクラスを作成して、「マイグレーション実部のSQL発行」だけしないようにしています。
今後 kysely 本体の更新次第で正常に動作しなくなる可能性があるので注意してください。(気づいたら追従します)
package.json への記載は以下のようになります。
設定ファイルのフィールドdryMigrateOutputが未指定のときはコンソールに出力、指定ありのときは指定されたファイルに出力します。

    "migrate:latest-dry": "kysely-extends-pg-query --mode migrate-latest --config config.ts --dry",

マイグレーション内容のユーティリティ

PostgreSQL固有の機能(じゃないのもあるかもしれませんが)のユーティリティ関数群も作成しました。
引数に指定できる型は、 PostgreSQL 自体が受け付けるものより少ないです。(バージョンが古すぎる PostgreSQL だと逆に使えないものがあるかもしれません)
追加した関数の利用例は以下です。

  await commentOn(db, "table", "person", "test comment for table");
  await commentOn(db, "table", "person", null);
  await grantDBObj(db, "table", "select", { all: true, schema: "public" }, "target_role_name");
  await updateRowLevelSecurity(db, "person", "enable");
  await createPolicy(db, "person", { using: "true" });
  await dropPolicy(db, "person");

これらの利用例が発行するSQLを、下に表でまとめます。

関数 SQL例
commentOn comment on table "person" is 'test comment for table'
comment on table "person" is null
grantDBObj grant select on all tables in schema "public" to "target_role_name"
updateRowLevelSecurity alter table "person" enable row level security
createPolicy create policy "person_policy" on "person" using(true)
dropPolicy drop policy "person_policy" on "person"

おわりに

今回の記事はここまでになります。
みなさまもよき kysely ライフを!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0