Open11
Drizzle ORMのメモ

Drizzleに入門したのでメモしていく

DBはPostgreSQL

drizzle.config.tsはこんな感じ
import { defineConfig } from 'drizzle-kit';
const databaseUrl =
process.env.DATABASE_URL ||
'postgresql://postgres:postgres@127.0.0.1:54322/postgres';
export default defineConfig({
schema: './app/backend/db/schemas/**',
out: './app/backend/db/migrations',
dialect: 'postgresql',
dbCredentials: {
url: databaseUrl,
},
});
schemaファイルはschemas配下に書けば認識してくれる

共通するカラムはこんな感じで切り出しておくと使いやすい
import { timestamp, uuid } from 'drizzle-orm/pg-core';
export const id = uuid('id').primaryKey().defaultRandom();
const createdAt = timestamp('created_at', { withTimezone: true })
.defaultNow()
.notNull();
const updatedAt = timestamp('updated_at', { withTimezone: true })
.defaultNow()
.notNull();
export const defaultTimestamps = {
createdAt,
updatedAt,
};
export const schemaBase = {
id,
createdAt,
updatedAt,
};

generate する際は名前を指定したほうがよい。
でないと、自動で名前が作成されてわかりにくくなる
npx drizzle-kit generate --config drizzle.config.ts --name=create_hoges_table

--custom
を付けると空のSQLファイルができるのでシードデータなど追加するのに便利
npx drizzle-kit generate --config drizzle.config.ts --custom --name=seed_hoges_table
INSERT INTO "hoges" ("name") VALUES ('hogehoge');
INSERT INTO "hoges" ("name") VALUES ('foofoo');

generateは名前を付けつつ細かく実行したほうが、何をしているのかがわかりやすい

generateしてミスったら drizzle-kit drop
で削除できる

- migrate実行したあとにrollbackはできない
- じゃあどうやってrollbackするんだ?
- おそらく打ち消す感じのスキーマ か customで空のsqlファイル作成して対応する感じかな

これを参考に ON UPDATE CURRENT_TIMESTAMP
の対応をする
CREATE FUNCTION refresh_updated_at_step1() RETURNS trigger AS
$$
BEGIN
IF NEW.updated_at = OLD.updated_at THEN
NEW.updated_at := NULL;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION refresh_updated_at_step2() RETURNS trigger AS
$$
BEGIN
IF NEW.updated_at IS NULL THEN
NEW.updated_at := OLD.updated_at;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION refresh_updated_at_step3() RETURNS trigger AS
$$
BEGIN
IF NEW.updated_at IS NULL THEN
NEW.updated_at := CURRENT_TIMESTAMP;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
テーブル作成するときは忘れずにtriggerをセットする
CREATE TRIGGER refresh_accounts_updated_at_step1
BEFORE UPDATE ON accounts
FOR EACH ROW
EXECUTE FUNCTION refresh_updated_at_step1();
CREATE TRIGGER refresh_accounts_updated_at_step2
BEFORE UPDATE ON accounts
FOR EACH ROW
EXECUTE FUNCTION refresh_updated_at_step2();
CREATE TRIGGER refresh_accounts_updated_at_step3
BEFORE UPDATE ON accounts
FOR EACH ROW
EXECUTE FUNCTION refresh_updated_at_step3();
テーブル作成時に自動でトリガーをセットするイベントを作成しようとしたが権限を変えないといけなかったので、一旦generateしたあとに書くようにしている
漏れる可能性あるので、テストやら自動化するかで対策したい

シードデータの作成はcustom
オプションで空のsqlファイル作成してやるのがいいのか、
別途tsファイルで実行するのがいいのか迷っている
一旦sqlファイルで様子を見る