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에서 전환할 때 발생하는 대부분의 번거로움을 없애줍니다. 지원하는 기능은 다음과 같습니다:
- 열거형(enum)
- 모든 기본 및 비기본 컬럼을 포함한 테이블
- 인덱스
- 외래 키, 자기 참조 및 순환 외래 키
- 스키마
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(),
});