SQLite 컬럼 타입

정수(Integer)

공식 **SQLite 문서**에 따르면, SQLite 데이터베이스에 저장되거나 데이터베이스 엔진에 의해 조작되는 각 값은 NULL, INTEGER, REAL, TEXT, BLOB 중 하나의 저장 클래스를 가집니다.

이러한 모든 타입을 기본적으로 지원하지만, 만약 이로 충분하지 않다면 **커스텀 타입**을 자유롭게 생성할 수 있습니다.

중요

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

원한다면 데이터베이스 별칭을 사용할 수 있으며, casing 매개변수를 사용하여 Drizzle의 매핑 전략을 정의할 수도 있습니다.

이에 대해 더 자세히 알아보려면 여기를 참조하세요.

값의 크기에 따라 0, 1, 2, 3, 4, 6, 또는 8 바이트에 저장되는 부호 있는 정수입니다.

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

const table = sqliteTable('table', {
	id: integer()
});

// 정수 모드를 number, boolean, timestamp, timestamp_ms로 커스터마이즈할 수 있습니다.
integer({ mode: 'number' })
integer({ mode: 'boolean' })
integer({ mode: 'timestamp_ms' })
integer({ mode: 'timestamp' }) // Date
CREATE TABLE `table` (
	`id` integer
);
// 정수 기본 키를 자동 증가로 설정
integer({ mode: 'number' }).primaryKey({ autoIncrement: true })
CREATE TABLE `table` (
	`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL
);

Real

Real8바이트 IEEE 부동 소수점 숫자로 저장되는 실수 값을 나타냅니다.

import { real, sqliteTable } from "drizzle-orm/sqlite-core";

const table = sqliteTable('table', {
	real: real()
});
CREATE TABLE `table` (
	`real` real
);

텍스트

데이터베이스 인코딩(UTF-8, UTF-16BE, UTF-16LE)을 사용하여 저장된 텍스트 문자열입니다.

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

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

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

// "value1" | "value2" | null 타입으로 추론됨
text({ enum: ["value1", "value2"] })
text({ mode: 'json' })
text({ mode: 'json' }).$type()
CREATE TABLE `table` (
	`text` text
);

Blob

입력된 그대로 저장되는 데이터 덩어리입니다.

blob('', { mode: 'json' }) 대신 text('', { mode: 'json' })을 사용하는 것을 권장합니다. 왜냐하면 text는 JSON 함수를 지원하기 때문입니다:

현재 모든 JSON 함수는 인자 중 하나라도 BLOB이면 오류를 발생시킵니다. 이는 BLOB이 JSON의 바이너리 인코딩을 저장하기 위한 향후 개선을 위해 예약되어 있기 때문입니다.

자세한 내용은 **https://www.sqlite.org/json1.html**를 참고하세요.

import { blob, sqliteTable } from "drizzle-orm/sqlite-core";

const table = sqliteTable('table', {
	blob: blob()
});

blob()
blob({ mode: 'buffer' })
blob({ mode: 'bigint' })

blob({ mode: 'json' })
blob({ mode: 'json' }).$type()
CREATE TABLE `table` (
	`blob` blob
);

Blob 타입 추론을 위해 .$type<..>()을 지정할 수 있습니다. 이것은 런타임 값을 검사하지 않습니다. 기본값, 삽입 및 선택 스키마에 대한 컴파일 타임 보호를 제공합니다.

// { foo: string }로 추론됨
json: blob({ mode: 'json' }).$type<{ foo: string }>();

// string[]로 추론됨
json: blob({ mode: 'json' }).$type<string[]>();

// 컴파일되지 않음
json: blob({ mode: 'json' }).$type<{}>().default({});

Boolean 타입

SQLite는 기본적으로 boolean 데이터 타입을 지원하지 않습니다. 하지만 integer 컬럼을 boolean 모드로 지정할 수 있습니다. 이렇게 하면 코드에서 불리언 값을 다룰 수 있고, Drizzle은 이를 데이터베이스에 0과 1의 정수 값으로 저장합니다.

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

const table = sqliteTable('table', {
    id: integer({ mode: 'boolean' })
});
CREATE TABLE `table` (
    `id` integer
);

이 예제에서는 id 컬럼을 boolean 모드로 설정하여, 불리언 값을 저장할 수 있도록 합니다. 데이터베이스에는 이 값이 0 또는 1로 저장됩니다.

Bigint

SQLite에는 bigint 데이터 타입이 없기 때문에, Drizzle은 blob 컬럼을 위한 특별한 bigint 모드를 제공합니다. 이 모드를 사용하면 코드에서 BigInt 인스턴스를 다룰 수 있으며, Drizzle은 이를 데이터베이스에 blob 값으로 저장합니다.

import { blob, sqliteTable } from "drizzle-orm/sqlite-core";

const table = sqliteTable('table', {
    id: blob({ mode: 'bigint' })
});
CREATE TABLE `table` (
    `id` blob
);

위의 코드에서 blob 컬럼은 bigint 모드로 설정되어 있으며, 이는 데이터베이스에 blob 값으로 저장됩니다. 이를 통해 BigInt 값을 효율적으로 다룰 수 있습니다.

---

데이터 타입 커스터마이징

모든 컬럼 빌더는 .$type() 메서드를 제공합니다. 이 메서드를 사용하면 컬럼의 데이터 타입을 커스터마이징할 수 있습니다. 이 기능은 알려지지 않은 타입이나 브랜드 타입을 다룰 때 유용합니다.

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

const users = sqliteTable('users', {
  id: integer().$type<UserId>().primaryKey(),
  jsonField: blob().$type<Data>(),
});

위 예제에서 UserId는 브랜드 타입으로 정의되었고, Data는 일반 객체 타입입니다. .$type() 메서드를 사용해 각 컬럼에 맞는 타입을 지정할 수 있습니다.

NOT NULL 제약 조건

NOT NULL 제약 조건은 해당 컬럼이 NULL 값을 포함할 수 없음을 의미합니다.

const table = sqliteTable('table', { 
    numInt: integer().notNull() 
});
CREATE TABLE table (
    `numInt` integer NOT NULL
);

기본값 설정

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

명시적인 DEFAULT 절은 기본값을 NULL, 문자열 상수, 블롭 상수, 부호 있는 숫자, 또는 괄호로 둘러싸인 상수 표현식으로 지정할 수 있습니다.

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

const table = sqliteTable('table', {
	int1: integer().default(42),
	int2: integer().default(sql`(abs(42))`)
});
CREATE TABLE `table` (
	`int1` integer DEFAULT 42,
	`int2` integer DEFAULT (abs(42))
);

기본값은 대소문자를 구분하지 않는 특수 키워드인 CURRENT_TIME, CURRENT_DATE, 또는 CURRENT_TIMESTAMP 중 하나일 수도 있습니다.

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

const table = sqliteTable("table", {
  time: text().default(sql`(CURRENT_TIME)`),
  date: text().default(sql`(CURRENT_DATE)`),
  timestamp: text().default(sql`(CURRENT_TIMESTAMP)`),
});
CREATE TABLE `table` (
	`time` text DEFAULT (CURRENT_TIME),
	`date` text DEFAULT (CURRENT_DATE),
	`timestamp` text DEFAULT (CURRENT_TIMESTAMP)
);

$default() 또는 $defaultFn()을 사용하면 런타임에 기본값을 생성하고, 이 값을 모든 삽입 쿼리에서 사용할 수 있습니다. 이 함수들은 uuid, cuid, cuid2 등 다양한 구현을 활용하는 데 도움을 줄 수 있습니다.

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

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

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

$onUpdate() 또는 $onUpdateFn()을 사용하면 런타임에 기본값을 생성하고, 이 값을 모든 업데이트 쿼리에서 사용할 수 있습니다. 이 함수는 행이 업데이트될 때 호출되며, 반환된 값이 컬럼 값으로 사용됩니다. 만약 기본값(또는 $defaultFn)이 제공되지 않으면, 행이 삽입될 때도 이 함수가 호출되고, 반환된 값이 컬럼 값으로 사용됩니다.

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

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

const table = sqliteTable('table', {
    alwaysNull: text().$type().$onUpdate(() => null),
});