Drizzle ORMにおけるタイムゾーン付きTimestamp

SQLのTIMESTAMP、TIMESTAMPTZ、DATETIMEカラムをPostgreSQL、MySQL、SQLiteにおける適切なタイムゾーン処理でDrizzle ORMスキーマに変換します。

Dialect-Specific

詳細な説明

Drizzleにおけるタイムスタンプ処理

日付と時刻の型は、SQLの中で最もダイアレクト固有の側面の一つです。Drizzleはダイアレクトに応じて異なるビルダーとオプションを提供します。

PostgreSQLタイムスタンプ

PostgreSQLはTIMESTAMP(タイムゾーンなし)とTIMESTAMPTZ(タイムゾーン付き)を区別します:

CREATE TABLE events (
  id SERIAL PRIMARY KEY,
  name VARCHAR(200) NOT NULL,
  starts_at TIMESTAMP NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
import { pgTable, serial, timestamp, varchar } from "drizzle-orm/pg-core";
import { sql } from "drizzle-orm";

export const events = pgTable("events", {
  id: serial("id").primaryKey(),
  name: varchar("name", { length: 200 }).notNull(),
  startsAt: timestamp("starts_at").notNull(),
  createdAt: timestamp("created_at", { withTimezone: true }).default(sql`CURRENT_TIMESTAMP`),
});

キーオプションは{ withTimezone: true }で、データベースでTIMESTAMPTZを使用するようDrizzleに指示します。

MySQL DATETIMEとTIMESTAMP

MySQLには動作が異なる2つの類似型があります:

  • DATETIME: タイムゾーン変換なし、そのまま保存(範囲:1000-01-01〜9999-12-31)
  • TIMESTAMP: 保存時にUTCに変換(範囲:1970-01-01〜2038-01-19)
CREATE TABLE logs (
  id INT AUTO_INCREMENT PRIMARY KEY,
  event_time DATETIME NOT NULL,
  recorded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
import { datetime, mysqlTable, serial, timestamp } from "drizzle-orm/mysql-core";
import { sql } from "drizzle-orm";

export const logs = mysqlTable("logs", {
  id: serial("id").primaryKey(),
  eventTime: datetime("event_time").notNull(),
  recordedAt: timestamp("recorded_at").default(sql`CURRENT_TIMESTAMP`),
});

SQLiteの日付/時刻

SQLiteには専用の日付/時刻型がありません。日付は通常、ISO 8601形式のTEXT、UnixタイムスタンプとしてのINTEGER、またはユリウス日番号としてのREALとして保存されます:

import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
import { sql } from "drizzle-orm";

export const logs = sqliteTable("logs", {
  id: integer("id").primaryKey(),
  createdAt: text("created_at").default(sql`CURRENT_TIMESTAMP`),
});

一般的なデフォルト値

SQLデフォルト Drizzleデフォルト
CURRENT_TIMESTAMP .default(sql\CURRENT_TIMESTAMP`)`
NOW() .default(sql\CURRENT_TIMESTAMP`)`

ベストプラクティス

新しいプロジェクトでは、時点を表すカラムにはTIMESTAMPTZ(PostgreSQL)またはTIMESTAMP(MySQL)を使用し、特定のタイムゾーンコンテキストで時刻が意味を持つスケジュールイベントのようなカラムにはタイムゾーンなしのTIMESTAMP / DATETIMEを使用することが推奨されます。

ユースケース

さまざまなタイムゾーン処理パターンでタイムスタンプカラムを多用するデータベーススキーマを変換しており、Drizzleスキーマがタイムゾーンの動作を正しく表現することを確認する必要がある場合。

試してみる — SQL to Drizzle Schema

フルツールを開く