kysely とは
Typescript のクエリビルダーです。
手前味噌ですが去年紹介記事を書いています。
上の記事の時点ではPostgreSQL, MySQL, SQLiteが使えてましたがSQLServerも増えているみたいです。
本家のドキュメント(トップページ)はこちら
kysely におけるマイグレーション
マイグレーションファイルの書き方は knex とよく似ていますが、「マイグレーションの実行」部分を自分で書く必要があります。
その分、自由度が高いともいえますが、少し面倒です。
マイグレーションでほしい機能を自作する
手前味噌その2ですが、 kysely 系 npm パッケージをつくっています。
主に PostgreSQL に特化した追加機能を実装しています。
現在の最新バージョンは 0.2.4 です。
上の記事の時点では 0.1台でしたが、マイグレーション関係の機能を追加して 0.2 にしてみました。(バージョンのつけかた合ってる?)
また、 Node.js と Deno で一部ソースを共有できなさそうだったので、 Node.js オンリーの対応です。
マイグレーション実行
個々のプロジェクトでマイグレーション実行を書かなくて済むよう、コマンド化しました。
まず、接続先の情報などを記載する設定ファイルを作成します。
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 | データベース作成時のオプション、encodingやlocale等 |
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 ライフを!