PostgreSQL 컬럼 타입

모든 PostgreSQL 컬럼 타입을 기본적으로 지원하며, 이것으로 충분하지 않다면 **커스텀 타입**을 자유롭게 만들 수 있습니다.

중요

이 문서의 모든 예제는 데이터베이스 컬럼명 별칭을 사용하지 않으며, 컬럼명은 TypeScript 키에서 생성됩니다.

원하는 경우 컬럼명에 데이터베이스 별칭을 사용할 수 있으며, Drizzle에 대한 매핑 전략을 정의하기 위해 casing 파라미터를 사용할 수도 있습니다.

자세한 내용은 여기에서 확인할 수 있습니다.

integer

integer int int4 부호 있는 4바이트 정수

integer autoincrement가 필요한 경우 **serial**을 참조하세요.

import { integer, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
	int: integer()
});
CREATE TABLE "table" (
	"int" integer
);
import { sql } from "drizzle-orm";
import { integer, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
	int1: integer().default(10),
	int2: integer().default(sql`'10'::int`)
});
CREATE TABLE "table" (
	"int1" integer DEFAULT 10,
	"int2" integer DEFAULT '10'::int
);

smallint

smallint int2 작은 범위의 부호 있는 2바이트 정수

smallint autoincrement가 필요한 경우 **smallserial**을 참조하세요.

import { smallint, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
	smallint: smallint()
});
CREATE TABLE "table" (
	"smallint" smallint
);
import { sql } from "drizzle-orm";
import { smallint, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
	smallint1: smallint().default(10),
	smallint2: smallint().default(sql`'10'::smallint`)
});
CREATE TABLE "table" (
	"smallint1" smallint DEFAULT 10,
	"smallint2" smallint DEFAULT '10'::smallint
);

bigint

bigint int8 부호 있는 8바이트 정수

bigint autoincrement가 필요한 경우 **bigserial**을 참조하세요.

2^31 이상 2^53 미만의 값을 예상하는 경우 mode: 'number'를 사용하여 bigint 대신 JavaScript number로 처리할 수 있습니다.

import { bigint, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
	bigint: bigint({ mode: 'number' })
});

// will be inferred as `number`
bigint: bigint({ mode: 'number' })

// will be inferred as `bigint`
bigint: bigint({ mode: 'bigint' })
CREATE TABLE "table" (
	"bigint" bigint
);
import { sql } from "drizzle-orm";
import { bigint, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
	bigint1: bigint().default(10),
	bigint2: bigint().default(sql`'10'::bigint`)
});
CREATE TABLE "table" (
	"bigint1" bigint DEFAULT 10,
	"bigint2" bigint DEFAULT '10'::bigint
);

---

serial

serial serial4 자동 증가하는 4바이트 정수로, 고유 식별자 컬럼을 생성하는 표기법적 편의 기능입니다 (일부 다른 데이터베이스에서 지원하는 AUTO_INCREMENT 속성과 유사).

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { serial, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
  serial: serial(),
});
CREATE TABLE "table" (
	"serial" serial NOT NULL
);

smallserial

smallserial serial2 자동 증가하는 2바이트 정수로, 고유 식별자 컬럼을 생성하는 표기법적 편의 기능입니다 (일부 다른 데이터베이스에서 지원하는 AUTO_INCREMENT 속성과 유사).

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { smallserial, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
  smallserial: smallserial(),
});
CREATE TABLE "table" (
	"smallserial" smallserial NOT NULL
);

bigserial

bigserial serial8 자동 증가하는 8바이트 정수로, 고유 식별자 컬럼을 생성하는 표기법적 편의 기능입니다 (일부 다른 데이터베이스에서 지원하는 AUTO_INCREMENT 속성과 유사).

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

2^31 이상 2^53 미만의 값을 예상하는 경우 mode: 'number'를 사용하여 bigint 대신 JavaScript number로 처리할 수 있습니다.

import { bigserial, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
  bigserial: bigserial({ mode: 'number' }),
});
CREATE TABLE "table" (
	"bigserial" bigserial NOT NULL
);

---

boolean

PostgreSQL은 표준 SQL 타입인 boolean을 제공합니다.

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { boolean, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
	boolean: boolean()
});
CREATE TABLE "table" (
	"boolean" boolean
);

---

bytea

PostgreSQL은 표준 SQL 타입인 bytea를 제공합니다.

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { bytea, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
	bytea: bytea()
});
CREATE TABLE IF NOT EXISTS "table" (
	"bytea" bytea,
);

---

text

text 가변 길이(무제한) 문자열입니다.

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

{ enum: ["value1", "value2"] } 설정을 정의하여 insertselect 타입을 추론할 수 있으며, 런타임 값을 검사하지는 않습니다.

import { text, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
  text: text()
});

// will be inferred as text: "value1" | "value2" | null
text: text({ enum: ["value1", "value2"] })
CREATE TABLE "table" (
	"text" text
);

varchar

character varying(n) varchar(n) 가변 길이 문자열로, 최대 **n**개의 문자(바이트가 아님)를 저장할 수 있습니다.

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

{ enum: ["value1", "value2"] } 설정을 정의하여 insertselect 타입을 추론할 수 있으며, 런타임 값을 검사하지는 않습니다.

PostgreSQL 문서에 따르면 length 파라미터는 선택사항입니다.

import { varchar, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
  varchar1: varchar(),
  varchar2: varchar({ length: 256 }),
});

// will be inferred as text: "value1" | "value2" | null
varchar: varchar({ enum: ["value1", "value2"] }),
CREATE TABLE "table" (
	"varchar1" varchar,
	"varchar2" varchar(256)
);

char

character(n) char(n) 고정 길이의 공백으로 채워지는 문자열로, 최대 **n**개의 문자(바이트가 아님)를 저장할 수 있습니다.

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

{ enum: ["value1", "value2"] } 설정을 정의하여 insertselect 타입을 추론할 수 있으며, 런타임 값을 검사하지는 않습니다.

PostgreSQL 문서에 따르면 length 파라미터는 선택사항입니다.

import { char, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
  char1: char(),
  char2: char({ length: 256 }),
});

// will be inferred as text: "value1" | "value2" | null
char: char({ enum: ["value1", "value2"] }),
CREATE TABLE "table" (
	"char1" char,
	"char2" char(256)
);

---

numeric

numeric decimal 선택 가능한 정밀도를 가진 정확한 숫자입니다. 소수점 앞에 최대 131072자리, 소수점 뒤에 최대 16383자리까지 매우 큰 자릿수의 숫자를 저장할 수 있습니다.

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { numeric, pgTable } from "drizzle-orm/pg-core";

export const table = pgTable('table', {
  numeric1: numeric(),
  numeric2: numeric({ precision: 100 }),
  numeric3: numeric({ precision: 100, scale: 20 }),
  numericNum: numeric({ mode: 'number' }),
  numericBig: numeric({ mode: 'bigint' }),
});
CREATE TABLE "table" (
	"numeric1" numeric,
	"numeric2" numeric(100),
	"numeric3" numeric(100, 20),
	"numericNum" numeric,
	"numericBig" numeric
);

decimal

**numeric**의 별칭입니다.

real

real float4 단정밀도 부동소수점 숫자 (4바이트)

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { sql } from "drizzle-orm";
import { real, pgTable } from "drizzle-orm/pg-core";

const table = pgTable('table', {
	real1: real(),
	real2: real().default(10.10),
	real3: real().default(sql`'10.10'::real`),
});
CREATE TABLE "table" (
	"real1" real,
	"real2" real default 10.10,
	"real3" real default '10.10'::real
);

double precision

double precision float8 배정밀도 부동소수점 숫자 (8바이트)

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { sql } from "drizzle-orm";
import { doublePrecision, pgTable } from "drizzle-orm/pg-core";

const table = pgTable('table', {
	double1: doublePrecision(),
	double2: doublePrecision().default(10.10),
	double3: doublePrecision().default(sql`'10.10'::double precision`),
});
CREATE TABLE "table" (
	"double1" double precision,
	"double2" double precision default 10.10,
	"double3" double precision default '10.10'::double precision
);

---

json

json **RFC 7159**에 명시된 텍스트 형식의 JSON 데이터입니다.

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { sql } from "drizzle-orm";
import { json, pgTable } from "drizzle-orm/pg-core";

const table = pgTable('table', {
	json1: json(),
	json2: json().default({ foo: "bar" }),
	json3: json().default(sql`'{foo: "bar"}'::json`),
});
CREATE TABLE "table" (
	"json1" json,
	"json2" json default '{"foo": "bar"}'::json,
	"json3" json default '{"foo": "bar"}'::json
);

.$type<..>()을 지정하여 JSON 객체 추론을 할 수 있으며, 런타임 값을 검사하지는 않습니다. 기본값, insert 및 select 스키마에 대한 컴파일 타임 보호를 제공합니다.

// will be inferred as { foo: string }
json: json().$type<{ foo: string }>();

// will be inferred as string[]
json: json().$type<string[]>();

// won't compile
json: json().$type<string[]>().default({});

jsonb

jsonb 분해된 바이너리 JSON 데이터입니다.

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { jsonb, pgTable } from "drizzle-orm/pg-core";

const table = pgTable('table', {
	jsonb1: jsonb(),
	jsonb2: jsonb().default({ foo: "bar" }),
	jsonb3: jsonb().default(sql`'{foo: "bar"}'::jsonb`),
});
CREATE TABLE "table" (
	"jsonb1" jsonb,
	"jsonb2" jsonb default '{"foo": "bar"}'::jsonb,
	"jsonb3" jsonb default '{"foo": "bar"}'::jsonb
);

.$type<..>()을 지정하여 JSON 객체 추론을 할 수 있으며, 런타임 값을 검사하지는 않습니다. 기본값, insert 및 select 스키마에 대한 컴파일 타임 보호를 제공합니다.

// will be inferred as { foo: string }
jsonb: jsonb().$type<{ foo: string }>();

// will be inferred as string[]
jsonb: jsonb().$type<string[]>();

// won't compile
jsonb: jsonb().$type<string[]>().default({});

---

uuid

uuid

RFC 4122, ISO/IEC 9834-8:2005 및 관련 표준에 정의된 범용 고유 식별자(UUID)를 저장하는 데이터 타입입니다.

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { uuid, pgTable } from "drizzle-orm/pg-core";

const table = pgTable('table', {
  uuid1: uuid(),
  uuid2: uuid().defaultRandom(),
  uuid3: uuid().default('a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11')
});
CREATE TABLE "table" (
	"uuid1" uuid,
	"uuid2" uuid default gen_random_uuid(),
	"uuid3" uuid default 'a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11'
);

---

time

time timetz time with timezone time without timezone 타임존을 포함하거나 포함하지 않는 시간입니다.

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { time, pgTable } from "drizzle-orm/pg-core";

const table = pgTable('table', {
  time1: time(),
  time2: time({ withTimezone: true }),
  time3: time({ precision: 6 }),
  time4: time({ precision: 6, withTimezone: true })
});
CREATE TABLE "table" (
	"time1" time,
	"time2" time with timezone,
	"time3" time(6),
	"time4" time(6) with timezone
);

timestamp

timestamp timestamptz timestamp with time zone timestamp without time zone 타임존을 포함하거나 포함하지 않는 날짜와 시간입니다.

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { sql } from "drizzle-orm";
import { timestamp, pgTable } from "drizzle-orm/pg-core";

const table = pgTable('table', {
  timestamp1: timestamp(),
	timestamp2: timestamp({ precision: 6, withTimezone: true }),
	timestamp3: timestamp().defaultNow(),
	timestamp4: timestamp().default(sql`now()`),
});
CREATE TABLE "table" (
	"timestamp1" timestamp,
	"timestamp2" timestamp (6) with time zone,
	"timestamp3" timestamp default now(),
	"timestamp4" timestamp default now()
);

date 또는 string 추론 모드를 지정할 수 있습니다:

// will infer as date
timestamp: timestamp({ mode: "date" }),

// will infer as string
timestamp: timestamp({ mode: "string" }),

string 모드는 매핑을 수행하지 않습니다. 이 모드는 개발자가 필요에 따라 날짜 및 날짜 매핑을 직접 처리할 수 있도록 Drizzle ORM에 추가되었습니다. Drizzle은 원시 날짜를 데이터베이스 에서 문자열로 전달하므로, 동작은 가능한 한 예측 가능하고 데이터베이스 동작과 100% 일치해야 합니다.

date 모드는 날짜를 다루는 일반적인 방법입니다. Drizzle이 데이터베이스와 JS Date 객체 간의 모든 매핑을 처리합니다.

timestamptimestamp with timezone의 매핑 작동 방식:

PostgreSQL 문서에 명시된 바와 같이:

timestamp without time zone으로 결정된 리터럴에서 PostgreSQL은 타임존 표시를 자동으로 무시합니다. 즉, 결과 값은 입력 값의 날짜/시간 필드에서 파생되며 타임존에 대해 조정되지 않습니다.

timestamp with time zone의 경우, 내부적으로 저장되는 값은 항상 UTC(협정 세계시, 전통적으로 그리니치 표준시, GMT로 알려짐)입니다. 명시적인 타임존이 지정된 입력 값은 해당 타임존에 대한 적절한 오프셋을 사용하여 UTC로 변환됩니다. 입력 문자열에 타임존이 명시되지 않은 경우, 시스템의 TimeZone 파라미터로 표시된 타임존에 있는 것으로 가정하고 해당 타임존의 오프셋을 사용하여 UTC로 변환됩니다.

따라서 timestamp with timezone의 경우 Postgres 인스턴스에 설정된 타임존으로 변환된 문자열을 받게 됩니다. 다음 SQL 쿼리로 타임존을 확인할 수 있습니다:

show timezone;

date

date 달력 날짜 (년, 월, 일)

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { date, pgTable } from "drizzle-orm/pg-core";

const table = pgTable('table', {
	date: date(),
});
CREATE TABLE "table" (
	"date" date
);

date 또는 string 추론 모드를 지정할 수 있습니다:

// will infer as date
date: date({ mode: "date" }),

// will infer as string
date: date({ mode: "string" }),

interval

interval 시간 간격

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { interval, pgTable } from "drizzle-orm/pg-core";

const table = pgTable('table', {
	interval1: interval(),
  interval2: interval({ fields: 'day' }),
  interval3: interval({ fields: 'month' , precision: 6 }),
});
CREATE TABLE "table" (
	"interval1" interval,
	"interval2" interval day,
	"interval3" interval(6) month
);

---

point

point 기하학적 점 타입

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

point 타입은 데이터베이스에서 매핑하기 위한 2가지 모드가 있습니다: tuplexy.

const items = pgTable('items', {
 point: point(),
 pointObj: point({ mode: 'xy' }),
});
CREATE TABLE "items" (
	"point" point,
	"pointObj" point
);

line

line 기하학적 선 타입

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

line 타입은 데이터베이스에서 매핑하기 위한 2가지 모드가 있습니다: tupleabc.

const items = pgTable('items', {
 line: line(),
 lineObj: line({ mode: 'abc' }),
});
CREATE TABLE "items" (
	"line" line,
	"lineObj" line
);

---

enum

enum enumerated types 열거형(enum) 타입은 정적이고 순서가 있는 값의 집합으로 구성된 데이터 타입입니다. 여러 프로그래밍 언어에서 지원하는 enum 타입과 동등합니다. enum 타입의 예로는 요일이나 데이터의 상태 값 집합이 있습니다.

자세한 내용은 공식 PostgreSQL **문서**를 참조하세요.

import { pgEnum, pgTable } from "drizzle-orm/pg-core";

export const moodEnum = pgEnum('mood', ['sad', 'ok', 'happy']);

export const table = pgTable('table', {
  mood: moodEnum(),
});
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');

CREATE TABLE "table" (
	"mood" mood
);

---

Customizing data type

모든 컬럼 빌더에는 .$type() 메서드가 있으며, 이를 통해 컬럼의 데이터 타입을 커스터마이즈할 수 있습니다.

이는 예를 들어 unknown 또는 branded 타입에 유용합니다:

type UserId = number & { __brand: 'user_id' };
type Data = {
	foo: string;
	bar: number;
};

const users = pgTable('users', {
  id: serial().$type<UserId>().primaryKey(),
  jsonField: json().$type<Data>(),
});

Identity Columns

이 기능을 사용하려면 drizzle-orm@0.32.0 이상과 drizzle-kit@0.23.0 이상이 필요합니다.

PostgreSQL은 컬럼에 대한 고유 정수 값을 자동으로 생성하는 방법으로 identity 컬럼을 지원합니다. 이러한 값은 시퀀스를 사용하여 생성되며 GENERATED AS IDENTITY 절을 사용하여 정의할 수 있습니다.

Identity 컬럼의 타입

주요 기능

제한사항

사용 예제

import { pgTable, integer, text } from 'drizzle-orm/pg-core'

export const ingredients = pgTable("ingredients", {
  id: integer().primaryKey().generatedAlwaysAsIdentity({ startWith: 1000 }),
  name: text().notNull(),
  description: text(),
});

.generatedAlwaysAsIdentity() 함수에서 시퀀스에 사용 가능한 모든 속성을 지정할 수 있습니다. 또한 이러한 시퀀스에 대한 커스텀 이름을 지정할 수도 있습니다.

PostgreSQL 문서 참조.

Default value

DEFAULT 절은 INSERT 수행 시 사용자가 명시적으로 값을 제공하지 않은 경우 컬럼에 사용할 기본값을 지정합니다. 컬럼 정의에 명시적인 DEFAULT 절이 없으면 컬럼의 기본값은 NULL입니다.

명시적인 DEFAULT 절은 기본값이 NULL, 문자열 상수, blob 상수, 부호 있는 숫자 또는 괄호로 묶인 상수 표현식임을 지정할 수 있습니다.

import { sql } from "drizzle-orm";
import { integer, pgTable, uuid } from "drizzle-orm/pg-core";

const table = pgTable('table', {
	integer1: integer().default(42),
	integer2: integer().default(sql`'42'::integer`),
	uuid1: uuid().defaultRandom(),
	uuid2: uuid().default(sql`gen_random_uuid()`),
});
CREATE TABLE "table" (
	"integer1" integer DEFAULT 42,
	"integer2" integer DEFAULT '42'::integer,
	"uuid1" uuid DEFAULT gen_random_uuid(),
	"uuid2" uuid DEFAULT gen_random_uuid()
);

단순히 동일한 함수에 대한 별칭인 $default() 또는 $defaultFn()을 사용하는 경우, 런타임에 기본값을 생성하고 모든 insert 쿼리에서 이러한 값을 사용할 수 있습니다.

이러한 함수는 uuid, cuid, cuid2 등 다양한 구현을 활용하는 데 도움이 됩니다.

참고: 이 값은 drizzle-kit 동작에 영향을 주지 않으며, drizzle-orm에서 런타임에만 사용됩니다.

import { text, pgTable } from "drizzle-orm/pg-core";
import { createId } from '@paralleldrive/cuid2';

const table = pgTable('table', {
	id: text().$defaultFn(() => createId()),
});

단순히 동일한 함수에 대한 별칭인 $onUpdate() 또는 $onUpdateFn()을 사용하는 경우, 런타임에 기본값을 생성하고 모든 update 쿼리에서 이러한 값을 사용할 수 있습니다.

행이 업데이트될 때 호출될 동적 업데이트 값을 컬럼에 추가합니다. 함수가 호출되면 반환된 값이 컬럼 값으로 사용됩니다(값이 제공되지 않은 경우). 기본(또는 $defaultFn) 값이 제공되지 않은 경우, 행이 삽입될 때도 함수가 호출되고 반환된 값이 컬럼 값으로 사용됩니다.

참고: 이 값은 drizzle-kit 동작에 영향을 주지 않으며, drizzle-orm에서 런타임에만 사용됩니다.

import { integer, timestamp, text, pgTable } from "drizzle-orm/pg-core";

const table = pgTable('table', {
	updateCounter: integer().default(sql`1`).$onUpdateFn((): SQL => sql`${table.update_counter} + 1`),
	updatedAt: timestamp({ mode: 'date', precision: 3 }).$onUpdate(() => new Date()),
    	alwaysNull: text().$type<string | null>().$onUpdate(() => null),
});

Not null

NOT NULL 제약조건은 관련 컬럼에 NULL 값을 포함할 수 없음을 지정합니다.

import { integer, pgTable } from "drizzle-orm/pg-core";

const table = pgTable('table', {
	integer: integer().notNull(),
});
CREATE TABLE "table" (
	"integer" integer NOT NULL
);

Primary key

기본 키 제약조건은 컬럼 또는 컬럼 그룹이 테이블의 행에 대한 고유 식별자로 사용될 수 있음을 나타냅니다. 이를 위해서는 값이 고유하고 null이 아니어야 합니다.

import { serial, pgTable } from "drizzle-orm/pg-core";

const table = pgTable('table', {
	id: serial().primaryKey(),
});
CREATE TABLE "table" (
	"id" serial PRIMARY KEY NOT NULL
);