SQLite 列类型

基于官方的 SQLite 文档, 在 SQLite 数据库中存储的每个值(或由数据库引擎操作的值)都具有以下存储类别之一:NULLINTEGERREALTEXTBLOB

我们对它们都有原生支持,如果这还不够,可以自由地创建 自定义类型

数值型(Integer)

有符号整数,存储的字节数取决于值的大小,可以是 0123468

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

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

// 你可以自定义整数的模式,例如:number、boolean、timestamp、timestamp_ms
integer('id', { mode: 'number' })
integer('id', { mode: 'boolean' })
integer('id', { mode: 'timestamp_ms' })
integer('id', { mode: 'timestamp' }) // Date
CREATE TABLE `table` (
  `id` integer
);
// 使整数自增主键
integer('id', { mode: 'number' }).primaryKey({ autoIncrement: true })
CREATE TABLE `table` (
  `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL
);

浮点型(Real)

浮点数,以 8 字节的 IEEE 浮点数形式存储。

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

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

文本型(Text)

文本字符串,使用数据库编码(UTF-8UTF-16BEUTF-16LE)存储。

ℹ️

你可以定义 { enum: ["value1", "value2"] } 配置来推断 insertselect 类型,但它 不会 检查运行时值。

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

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

// 将被推断为 text: "value1" | "value2" | null
text('text', { enum: ["value1", "value2"] })
text('text', { mode: 'json' })
text('text', { mode: 'json' }).$type<{ foo: string }>()
CREATE TABLE `table` (
  `text` text
);

二进制大型对象(Blob)

二进制大型对象(Blob),存储的内容与输入完全一致。

ℹ️

建议使用 text('', { mode: 'json' }) 替代 blob('', { mode: 'json' }), 因为它支持 JSON 函数:

当前的所有 JSON 函数都会在其任意参数为 BLOB 时抛出错误, 因为 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('blob')
blob('blob', { mode: 'buffer' })
blob('blob', { mode: 'bigint' })

blob('blob', { mode: 'json' })
blob('blob', { mode: 'json' }).$type<{ foo: string }>()
CREATE TABLE `table` (
  `blob` blob
);

你可以使用 .$type<..>() 来推断 blob 类型,它 不会 检查运行时值。 它在编译时保护默认值、插入和选择模式的类型安全。

// 会推断为 { foo: string }
json: blob('json', { mode: 'json' }).$type<{ foo: string }>();

// 会推断为 string[]
json: blob('json', { mode: 'json' }).$type<string[]>();

// 无法编译通过
json: blob('json', { mode: 'json' }).$type<string[]>().default({});

布尔型(Boolean)

SQLite 没有原生的 boolean 数据类型,但是可以通过将 integer 列指定为 boolean 模式来实现布尔值的操作。 这样一来,你就可以在代码中操作布尔值,而 Drizzle 将它们存储为数据库中的 0 和 1 整数值。

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

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

长整型(Bigint)

由于 SQLite 中没有 bigint 数据类型,Drizzle 为 blob 列提供了一个特殊的 bigint 模式。 该模式允许你在代码中使用 BigInt 实例,并将其存储为二进制值在数据库中。

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

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

自定义列数据类型

每个列构建器都有一个 .$type() 方法,可用于自定义列的数据类型。这在处理未知或带类型的情况下非常有用。

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

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

列约束

非空约束(Not null)

NOT NULL 约束规定关联的列不能为空值。

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

默认值(Default value)

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('int1').default(42),
  int2: integer('int2').default(sql`(abs(42))`)
});
CREATE TABLE `table` (
  `int1` integer DEFAULT 42
  `int2` integer DEFAULT (abs(42))
);

默认值还可以是大小写无关的特殊关键字 CURRENT_TIMECURRENT_DATECURRENT_TIMESTAMP 之一。

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

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

当使用 $default()$defaultFn() 时,它们只是相同函数的不同别名,你可以在运行时生成默认值,并在所有插入查询中使用这些值。 这些函数可助你使用各种实现,如 uuidcuidcuid2 等等。

ℹ️

注意:这个值不影响 drizzle-kit 的行为,它仅在 drizzle-orm 的运行时使用。

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

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

当使用 $onUpdate()$onUpdateFn() 时,它们只是相同函数的不同别名,你可以在所有更新查询中生成默认值并使用这些值。

向列添加动态更新值。当行被更新时,将调用该函数,并在没有提供值时使用返回值作为列的值。 如果没有提供默认值(或 $defaultFn),则在插入行时也将调用该函数,并使用返回值作为列的值。

ℹ️

注意:这个值不影响 drizzle-kit 的行为,它仅在 drizzle-orm 的运行时使用。

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

const table = sqliteTable('table', {
    alwaysNull: text('always_null').$type<string | null>().$onUpdate(() => null),
});
Become a Gold Sponsor