Drizzle ORMにおけるPostgreSQL ENUM型
SQLをDrizzle ORMに変換する際のPostgreSQL ENUM型の処理方法。pgEnumとテキストベースの代替手段を解説します。
Dialect-Specific
詳細な説明
DrizzleにおけるENUM型
PostgreSQLはカラムを定義済みの値セットに制限するカスタムENUM型をサポートしています。Drizzleはこの目的でpgEnum()ビルダーを提供しますが、SQLコンバーターはインラインのENUM型をtext()にマッピングします。これはCREATE TABLE文だけではenum値を常に抽出できないためです。
SQLにおけるPostgreSQL ENUM
CREATE TYPE status AS ENUM ('active', 'inactive', 'suspended');
CREATE TABLE accounts (
id SERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL,
status status NOT NULL DEFAULT 'active'
);
pgEnumを使用したDrizzle
DrizzleのpgEnum()はテーブルの外側で定義されます:
import { pgEnum, pgTable, serial, varchar } from "drizzle-orm/pg-core";
export const statusEnum = pgEnum("status", ["active", "inactive", "suspended"]);
export const accounts = pgTable("accounts", {
id: serial("id").primaryKey(),
email: varchar("email", { length: 255 }).notNull(),
status: statusEnum("status").notNull().default("active"),
});
コンバーターの動作
SQLコンバーターはENUM型のカラムをtext()にマッピングします。理由は:
- CREATE TYPEは別文:
CREATE TYPE ... AS ENUM文はCREATE TABLEとは別であり、コンバーターはCREATE TABLEの解析に焦点を当てています。 - インラインENUM構文: MySQLのインライン
ENUM('a', 'b', 'c')構文は値を抽出するために特別な解析が必要です。
変換後、適切な箇所でtext()カラムを手動でpgEnum()に置き換える必要があります。
MySQL ENUMの代替
MySQLはカラム定義でインラインENUMをサポートしています:
CREATE TABLE accounts (
id INT AUTO_INCREMENT PRIMARY KEY,
role ENUM('admin', 'user', 'moderator') NOT NULL
);
Drizzleのmysql-coreはmysqlEnum()を提供します:
import { mysqlEnum, mysqlTable, serial } from "drizzle-orm/mysql-core";
export const accounts = mysqlTable("accounts", {
id: serial("id").primaryKey(),
role: mysqlEnum("role", ["admin", "user", "moderator"]).notNull(),
});
CHECK制約を使用したテキスト
SQLite(ネイティブENUMがない)では、型安全性のためにTypeScript共用体型とtext()を使用します:
export const accounts = sqliteTable("accounts", {
role: text("role", { enum: ["admin", "user", "moderator"] }).notNull(),
});
ユースケース
PostgreSQLデータベースがステータスフィールド、ロール、カテゴリにENUM型を使用しており、基本的なテーブル構造の変換後にDrizzle ORMでそれらをどのように表現するかを知る必要がある場合。