PostgreSQL 列类型

我们原生支持所有这些类型,但如果这还不够,您可以随意创建 自定义类型

重要提示

本文档的所有示例均不使用数据库列名别名,列名均由 TypeScript 键生成。

您可以根据需要使用数据库列名别名,也可以使用 casing 参数为 Drizzle 定义映射策略。

您可以在此处了解更多信息。

integer

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

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

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

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

// will be inferred as `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

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

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

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

---

boolean

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

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 IF NOT EXISTS "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 IF NOT EXISTS "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 IF NOT EXISTS "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 IF NOT EXISTS "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 IF NOT EXISTS "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 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
);

您可以为 JSON 对象推断指定 .$type<..>(),它**不会**检查运行时值。它为默认值、插入和选择模式提供了编译时保护。

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

您可以为 JSON 对象推断指定 .$type<..>(),它**不会**检查运行时值。它为默认值、插入和选择模式提供了编译时保护。

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

---

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 IF NOT EXISTS "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 IF NOT EXISTS "table" (
	"timestamp1" timestamp,
	"timestamp2" timestamp (6) with time zone,
	"timestamp3" timestamp default now(),
	"timestamp4" timestamp default now()
);

您可以指定 datestring 推断模式

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

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

string 模式不会为您执行任何映射。添加此模式是为了让开发者可以根据自身需求自行处理日期和日期映射。Drizzle 会将原始日期作为字符串在数据库之间 传入传出,因此其行为应尽可能可预测,并与数据库行为 100% 一致。

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

timestamptimestamp with timezone 的映射工作原理

如 PostgreSQL 文档所述

对于被确定为不带时区的 `timestamp` 字面量,PostgreSQL 将静默忽略任何时区指示。也就是说,结果值是根据输入值中的日期/时间字段派生的,并且不会根据时区进行调整。

对于带时区的 `timestamp`,内部存储的值始终是 UTC(世界协调时间,传统上称为格林威治标准时间,GMT)。如果输入值明确指定了时区,则会使用该时区的相应偏移量将其转换为 UTC。如果输入字符串中未声明时区,则假定它位于系统 `TimeZone` 参数指示的时区中,并使用该时区的偏移量转换为 UTC。

因此,对于 `timestamp with timezone`,您将获得转换为 PostgreSQL 实例中设置的时区的字符串。您可以使用此 SQL 查询来检查时区

show timezone;

date

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 推断模式

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

---

point

point
几何点类型

更多信息请参考 PostgreSQL 官方**文档**。

`point` 类型有两种数据库映射模式:`tuple` 和 `xy`。

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

line

line
几何线类型

更多信息请参考 PostgreSQL 官方**文档**。

`line` 类型有两种数据库映射模式:`tuple` 和 `abc`。

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

---

enum

enum enumerated types
枚举 (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>(),
});

标识列

要使用此功能,您需要 [email protected] 或更高版本以及 [email protected] 或更高版本。

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