PostgreSQL 列类型

我们对所有这些都提供原生支持,如果这些不够满足您的需求,欢迎创建 自定义类型

important

本部分文档中的所有示例都不使用数据库列名别名,列名是从 TypeScript 键生成的。

如果需要,您可以在列名中使用数据库别名,并且您也可以使用 casing 参数定义 Drizzle 的映射策略。

您可以在 这里 阅读更多相关信息。

整数

integer int int4
带符号的 4 字节整数

如果您需要 integer 自增,请参考 serial.

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

export const table = pgTable('table', {
    int: integer()
});
CREATE TABLE IF NOT EXISTS "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 IF NOT EXISTS "table" (
	"int1" integer DEFAULT 10
    "int2" integer DEFAULT '10'::int
);

小整数

smallint int2
小范围带符号的 2 字节整数

如果您需要 smallint 自增,请参考 smallserial.

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

export const table = pgTable('table', {
    smallint: smallint()
});
CREATE TABLE IF NOT EXISTS "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 IF NOT EXISTS "table" (
	"smallint1" smallint DEFAULT 10
    "smallint2" smallint DEFAULT '10'::smallint
);

大整数

bigint int8
带符号的 8 字节整数

如果您需要 bigint 自增,请参考 bigserial.

如果您预期的值在 2^31 以上但低于 2^53,可以利用 mode: 'number' 并处理 JavaScript 数字而不是 bigint。

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

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

// 将推导为 `number`
bigint: bigint({ mode: 'number' })

// 将推导为 `bigint`
bigint: bigint({ mode: 'bigint' })
CREATE TABLE IF NOT EXISTS "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 IF NOT EXISTS "table" (
	"bigint1" bigint DEFAULT 10
    "bigint2" bigint DEFAULT '10'::bigint
);

---

自增整数

serial serial4
自动递增的 4 字节整数,为创建唯一标识符列提供书面方便(类似于一些其他数据库支持的 AUTO_INCREMENT 属性)。

有关更多信息,请参阅官方 PostgreSQL 文档.

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

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

小自增整数

smallserial serial2
自动递增的 2 字节整数,为创建唯一标识符列提供书面方便(类似于一些其他数据库支持的 AUTO_INCREMENT 属性)。

有关更多信息,请参阅官方 PostgreSQL 文档.

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

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

大自增整数

bigserial serial8
自动递增的 8 字节整数,为创建唯一标识符列提供书面方便(类似于一些其他数据库支持的 AUTO_INCREMENT 属性)。

有关更多信息,请参阅官方 PostgreSQL 文档.

如果您预期的值在 2^31 以上但低于 2^53,您可以利用 mode: 'number' 并处理 JavaScript 数字而不是 bigint。

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

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

---

布尔值

PostgreSQL 提供标准 SQL 类型布尔值。

有关更多信息,请参阅官方 PostgreSQL 文档.

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

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

---

文本

text
可变长度(无限制)字符字符串。

有关更多信息,请参阅官方 PostgreSQL 文档.

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

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

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

// 将推导为 text: "value1" | "value2" | null
text: text({ enum: ["value1", "value2"] })
CREATE TABLE IF NOT EXISTS "table" (
    "text" text,
);

可变字符

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 }),
});

// 将推导为 text: "value1" | "value2" | null
varchar: varchar({ enum: ["value1", "value2"] }),
CREATE TABLE IF NOT EXISTS "table" (
    "varchar1" varchar,
    "varchar2" varchar(256),
);

固定字符

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 }),
});

// 将推导为 text: "value1" | "value2" | null
char: char({ enum: ["value1", "value2"] }),
CREATE TABLE IF NOT EXISTS "table" (
    "char1" char,
    "char2" char(256),
);

---

数值

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 }),
});
CREATE TABLE IF NOT EXISTS "table" (
    "numeric1" numeric,
    "numeric2" numeric(100),
    "numeric3" numeric(100, 20),
);

十进制

numeric. 的别名

实数

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),
	real2: real().default(sql`'10.10'::real`),
});
CREATE TABLE IF NOT EXISTS "table" (
    "real1" real,
    "real2" real default 10.10,
	"real2" real default '10.10'::real
);

双精度

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 IF NOT EXISTS "table" (
    "double1" double precision,
    "double2" double precision default 10.10,
    "double3" double precision default '10.10'::double precision,
);

---

JSON

json
文本 JSON 数据,如 RFC 7159. 中所规定。

有关更多信息,请参阅官方 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 IF NOT EXISTS "table" (
    "json1" json,
    "json2" json default '{"foo": "bar"}'::json,
    "json3" json default '{"foo": "bar"}'::json,
);

您可以指定 .$type<..>() 进行 JSON 对象推导,它 不会 检查运行时值。 它为默认值、插入和选择 схем提供编译时保护。

// 将推导为 { foo: string }
json: json().$type<{ foo: string }>();

// 将推导为 string[]
json: json().$type<string[]>();

// 不会编译
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 IF NOT EXISTS "table" (
    "jsonb1" jsonb,
    "jsonb2" jsonb default '{"foo": "bar"}'::jsonb,
    "jsonb3" jsonb default '{"foo": "bar"}'::jsonb,
);

您可以指定 .$type<..>() 进行 JSON 对象推导,它 不会 检查运行时值。 它为默认值、插入和选择 схем提供编译时保护。

// 将推导为 { foo: string }
jsonb: jsonb().$type<{ foo: string }>();

// 将推导为 string[]
jsonb: jsonb().$type<string[]>();

// 不会编译
jsonb: jsonb().$type<string[]>().default({});

---

时间

time timetz 带时区的时间 不带时区的时间
一天中的时间,可以带时区或不带时区。

有关更多信息,请参阅官方 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 IF NOT EXISTS "table" (
    "time1" time,
    "time2" time with timezone,
    "time3" time(6),
    "time4" time(6) with timezone,
);

时间戳

timestamp timestamptz 带时区的时间戳 不带时区的时间戳
带时区或不带时区的日期和时间。

有关更多信息,请参阅官方 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 IF NOT EXISTS "table" (
    "timestamp1" timestamp,
    "timestamp2" timestamp (6) with time zone,
    "timestamp3" timestamp default now(),
    "timestamp4" timestamp default now(),
);

您可以指定 datestring 推导模式:

// 将推导为 date
timestamp: timestamp({ mode: "date" }),

// 将推导为 string
timestamp: timestamp({ mode: "string" }),

string 模式并不会为您执行任何映射。 此模式是为了让开发者能够根据其需求自己处理日期和日期映射而添加给 Drizzle ORM 的。 Drizzle 将原样传递原始日期作为字符串,tofrom 数据库, 因此其行为应尽可能可预测,且与数据库行为 100% 一致。

date 模式是处理日期的常规方式。Drizzle 将处理数据库和 JS Date 对象之间的所有映射。

如何映射 timestamp带时区的时间戳 的方式:

正如 PostgreSQL 文档所述:

在被确定为不带时区的时间戳的字面量中,PostgreSQL 将静默忽略任何时区指示。 也就是说,结果值是根据输入值中的日期/时间字段得出的,并且未根据时区进行调整。

对于带时区的时间戳来说,内部存储的值始终为 UTC(协调世界时间,传统上称为格林威治标准时间 GMT)。 指定了显式时区的输入值将使用该时区的适当偏移量转换为 UTC。 如果输入字符串中未指定时区,则假定其在系统的 TimeZone 参数指示的时区, 并使用该时区区域的偏移值转换为 UTC。

因此,对于 带时区的时间戳,您将收到转换为您 Postgres 实例中设置的时区的字符串。 您可以使用以下 SQL 查询检查时区:

show timezone;

日期

date
日历日期(年,月,日)

有关更多信息,请参阅官方 PostgreSQL 文档.

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

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

您可以指定 datestring 推导模式:

// 将推导为 date
date: date({ mode: "date" }),

// 将推导为 string
date: date({ mode: "string" }),

时间间隔

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 IF NOT EXISTS "table" (
    "interval1" interval,
    "interval2" interval day,
    "interval3" interval(6) month,
);

---

point
几何点类型

有关更多信息,请参阅官方 PostgreSQL 文档.

类型 point 有 2 种从数据库映射的模式:tuplexy

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

线

line
几何线类型

有关更多信息,请参阅官方 PostgreSQL 文档.

类型 line 有 2 种从数据库映射的模式:tupleabc

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

---

枚举

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 IF NOT EXISTS "table" (
    "mood" mood,
);

---

自定义数据类型

每个列构建器都有一个 .$type() 方法,允许您自定义列的数据类型。

这在处理未知或品牌类型时很有用:

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>(),
});

身份列

要使用此功能,您需要安装 drizzle-orm@0.32.0 或更高版本,以及 drizzle-kit@0.23.0 或更高版本。

PostgreSQL 支持身份列作为自动生成列的唯一整数值的方式。这些值是使用序列生成的,可以使用 GENERATED AS 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 子句指定在用户执行 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 IF NOT EXISTS "table" (
    "integer1" integer DEFAULT 42,
    "integer2" integer DEFAULT '42'::integer,
    "uuid1" uuid DEFAULT gen_random_uuid(),
    "uuid2" uuid DEFAULT gen_random_uuid()
);

当使用 $default()$defaultFn() 时,这两个方法只是同一个函数的不同别名, 您可以在运行时生成默认值并在所有插入查询中使用这些值。

这些函数可以帮助您利用各种实现,例如 uuidcuidcuid2 等等。

注意:此值不会影响 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() 时,这两个函数只是同一个函数的不同别名, 您可以在运行时生成默认值并在所有更新查询中使用这些值。

它向列添加动态更新值。该函数将在行更新时调用, 返回的值将用作列值(如果未提供)。 如果未提供默认值(或 $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 约束规定相关列不得包含 NULL 值。

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

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

主键

主键约束表示列或列组可用作表中行的唯一标识符。 这要求值既独特又非空。

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

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