DrizzleORM v0.16.2 릴리스
Jan 21, 2023

Drizzle ORM은 SQL 스키마와 자동 마이그레이션 생성을 위한 CLI의 진실의 원천으로 사용할 수 있는 타입스크립트 ORM이자 쿼리 빌더입니다.

지난 주요 업데이트 이후로 많은 요청된 기능들이 추가되었습니다 🚀

🎉 PostgreSQL 스키마

이제 PostgreSQL 스키마를 선언하고, 해당 스키마 내에 생성될 테이블을 정의할 수 있습니다.

// src/schema.ts
import { pgSchema } from "drizzle-orm-pg";

export const mySchema = pgSchema("my_schema");

export const users = mySchema("users", {
  id: serial("id").primaryKey(),
  name: text("name"),
  email: text("email"),
});
CREATE SCHEMA "my_schema";

CREATE TABLE IF NOT EXISTS "my_schema"."users" (
	"id" serial PRIMARY KEY NOT NULL,
	"name" text,
	"email" text
);

drizzle-kit은 필요한 모든 SQL 마이그레이션을 자동으로 생성합니다.

drizzle-kit generate:pg --schema=src/schema.ts --out=migrations/ 

🎉 MySQL 데이터베이스/스키마

이제 MySQL 데이터베이스/스키마와 그 안에 생성할 테이블을 선언할 수 있습니다.

// schema.ts
import { mysqlSchema } from "drizzle-orm-mysql";

const mySchema = mysqlSchema("my_schema");

const users = mySchema("users", {
  id: serial("id").primaryKey(),
  name: text("name"),
  email: text("email"),
});

drizzle-kit은 필요한 모든 SQL 마이그레이션을 자동으로 생성합니다.

drizzle-kit generate:mysql --schema=src/schema.ts --out=migrations/

이 명령어는 자동으로 SQL 마이그레이션을 생성합니다.

CREATE DATABASE `my_schema`;

CREATE TABLE `my_schema`.`users` (
	`id` serial PRIMARY KEY NOT NULL,
	`name` text,
	`email` text
);

🎉 PostgreSQL 스키마 추출 기능 소개

이제 drizzle-kit을 사용해 기존 PostgreSQL 데이터베이스의 스키마를 몇 초 만에 추출할 수 있습니다. 이 기능은 기존 ORM이나 일반 SQL에서 전환할 때 발생하는 대부분의 번거로움을 없애줍니다. 지원하는 기능은 다음과 같습니다:

drizzle-kit introspect:pg --out=migrations/ --connectionString=postgresql://user:pass@host:port/db_name

위 명령어를 실행하면 schema.ts 파일이 생성됩니다.

export const myEnum = pgEnum("my_enum", ["one", "two", "three"]);
export const mySchema = pgSchema("my_schema");

export const users = mySchema("users", {
  id: serial("id").primaryKey(),
  name: text("name"),
  email: text("email"),
});

export const users2 = pgTable("users2", {
  id: serial("id").primaryKey(),
  name: varchar("name2"),
  enum: myEnum("enum"),
});

export const allColumns = pgTable("all_columns", {
  sm: smallint("smallint"),
  smdef: smallint("smallint_def").default(10),
  int: integer("integer"),
  intdef: integer("integer_def").default(10),
  numeric: numeric("numeric"),
  numeric2: numeric("numeric2", { precision: 7 }),
  numeric3: numeric("numeric3", { scale: 7 }),
  numeric4: numeric("numeric4", { precision: 7, scale: 7 }),
  numericdef: numeric("numeridef").default("100"),
  bigint: bigint("bigint", { mode: "number" }),
  bigintdef: bigint("bigint", { mode: "number" }).default(100),
  bool: boolean("boolean"),
  booldef: boolean("boolean_def").default(true),
  text: text("text"),
  textdef: text("textdef").default("text"),
  varchar: varchar("varchar"),
  varchardef: varchar("varchardef").default("text"),
  serial: serial("serial"),
  bigserial: bigserial("bigserial", { mode: "bigint" }),
  decimal: decimal("decimal", { precision: 100, scale: 2 }),
  decimaldef: decimal("decimaldef", { precision: 100, scale: 2 }).default(
    "100.0",
  ),
  doublePrecision: doublePrecision("decimal"),
  doublePrecisiondef: doublePrecision("decimaldef").default(100.0),
  real: real("real"),
  realdef: real("decimaldef").default(100.0),
  json: json("json"),
  jsondef: json("jsondef").default({ attr: "value" }),
  jsonb: jsonb("jsonb"),
  jsonbdef: jsonb("jsonbdef").default({ attr: "value" }),
  time: time("time"),
  time2: time("time2", { precision: 6, withTimezone: true }),
  timedefnow: time("timedefnow").defaultNow(),
  timestamp: timestamp("timestamp"),
  timestamp2: timestamp("timestamp2", { precision: 6, withTimezone: true }),
  timestamp3: timestamp("timestamp3", { withTimezone: true }),
  timestamp4: timestamp("timestamp4", { precision: 4 }),
  timestampdef: timestamp("timestampdef").defaultNow(),
  date: date("date", { mode: "date" }),
  datedef: date("datedef").defaultNow(),
  interval: interval("interval"),
  intervaldef: interval("intervaldef").default("10 days"),
});

export const cyclic1 = pgTable("cyclic1", {
  id: serial("id").primaryKey(),
  ext2: integer("ext2").references(() => cyclic2.id),
});

export const cyclic2 = pgTable("cyclic2", {
  id: serial("id").primaryKey(),
  ext1: integer("ext1").references((): AnyPgColumn => cyclic1.id),
});

export const example = pgTable(
  "example",
  {
    id: serial("id").primaryKey(),
    reportsTo: integer("reports_to"),
  },
  (table) => {
    return {
      reportsToFK: foreignKey({
        columns: [table.reportsTo],
        foreignColumns: [table.id],
      }),
    };
  },
);

🎉 Postgres.js 드라이버 지원 추가

이제 postgres.js를 완벽하게 지원합니다. 가볍고 빠른 드라이버입니다 🚀

// schema.ts
import { pgTable, serial, text, varchar } from "drizzle-orm-pg";
export const users = pgTable("users", {
  id: serial("id").primaryKey(),
  fullName: text("full_name"),
  phone: varchar("phone", { length: 256 }),
});

// index.ts
import { drizzle, PostgresJsDatabase } from "drizzle-orm-pg/postgres.js";
import postgres from "postgres";
import { users } from "./schema";

const client = postgres(connectionString);
const db: PostgresJsDatabase = drizzle(client);

const allUsers = await db.select(users);

PostgreSQL 전체 문서는 여기에서 확인할 수 있습니다.

🎉 PostgreSQL과 MySQL 타입

여러분이 필요한 비네이티브 PostgreSQL 또는 MySQL 타입을 생성할 수 있도록 유용한 연산자를 추가했습니다.

// PostgreSQL
const customText = customType({
  dataType() {
    return "text";
  },
});

const usersTable = pgTable("users", {
  name: customText("name").notNull(),
});

// MySQL
const customText = customType({
  dataType() {
    return "text";
  },
});

const usersTable = mysqlTable("users", {
  name: customText("name").notNull(),
});