createSelectSchema creates Valibot schema from table for query validation
createSelectSchema from drizzle-orm/valibot generates a Valibot validation schema from a Drizzle table definition. The schema reflects only the columns actually selected in a query. If a query selects specific columns, the schema validates only those columns; if a query selects all columns, the schema validates all columns. This can be used to validate API responses.
createInsertSchema creates Valibot schema for insert operations
createInsertSchema from drizzle-orm/valibot generates a Valibot validation schema for data to be inserted into the database. Generated columns with generatedAlwaysAsIdentity are not required in the schema. Columns marked notNull without defaults are required. This can be used to validate API requests before inserting.
createUpdateSchema creates Valibot schema for update operations
createUpdateSchema from drizzle-orm/valibot generates a Valibot validation schema for data to be updated in the database. All fields become optional, allowing partial updates. This can be used to validate API requests before updating.
Schema refinements extend or overwrite field validation in Drizzle Valibot
Each createSelectSchema, createInsertSchema, and createUpdateSchema function accepts an optional second parameter for refinements. Pass a callback function receiving the field schema to extend or modify it using Valibot pipe. Pass a Valibot schema directly to completely overwrite a field's validation, including its nullability.
Drizzle Valibot supports views and enums in schema generation
createSelectSchema works with pgView and pgEnum in addition to pgTable. For enums, it generates a Valibot enum schema. For views, it generates the same schema as for the underlying table.
Valibot schema for pg.boolean()
The Drizzle pg.boolean() column type maps to Valibot boolean().
Valibot schema for pgEnum
pgEnum('name', ['val1', 'val2']) maps to Valibot enum({ val1: "val1", val2: "val2" }).
Valibot schema for pg.date() and pg.timestamp() with mode date
pg.date({ mode: 'date' }) and pg.timestamp({ mode: 'date' }) map to Valibot date().
Valibot schema for string-mode date types
pg.date({ mode: 'string' }), pg.timestamp({ mode: 'string' }), pg.cidr(), pg.inet(), pg.interval(), pg.macaddr(), pg.macaddr8(), pg.numeric(), pg.text(), pg.sparsevec(), and pg.time() all map to Valibot string().
Valibot schema for pg.bit()
pg.bit({ dimensions: ... }) maps to pipe(string(), regex(/^[01]+$/), maxLength(dimensions)) in Valibot.
Valibot schema for pg.uuid()
pg.uuid() maps to pipe(string(), uuid()) in Valibot.
Valibot schema for pg.varchar()
pg.varchar({ length: ... }) maps to pipe(string(), maxLength(length)) in Valibot.
Valibot schema for text with enum
pg.text({ enum: ... }), pg.char({ enum: ... }), and pg.varchar({ enum: ... }) all map to Valibot enum(enum).
Valibot schema for pg.real()
pg.real() maps to pipe(number(), minValue(-8_388_608), maxValue(8_388_607)) in Valibot, representing 24-bit integer limits.
Valibot schema for pg.integer() and pg.serial()
pg.integer() and pg.serial() map to pipe(number(), minValue(-2_147_483_648), maxValue(2_147_483_647), integer()) in Valibot, representing 32-bit integer limits.
Valibot schema for pg.doublePrecision()
pg.doublePrecision() maps to pipe(number(), minValue(-140_737_488_355_328), maxValue(140_737_488_355_327)) in Valibot, representing 48-bit integer limits.
Valibot schema for pg.bigint() and pg.bigserial() with mode number
pg.bigint({ mode: 'number' }) and pg.bigserial({ mode: 'number' }) map to pipe(number(), minValue(-9_007_199_254_740_991), maxValue(9_007_199_254_740_991), integer()) in Valibot, representing JavaScript's minimum and maximum safe integers.
Valibot schema for pg.bigint() and pg.bigserial() with mode bigint
pg.bigint({ mode: 'bigint' }) and pg.bigserial({ mode: 'bigint' }) map to pipe(bigint(), minValue(-9_223_372_036_854_775_808n), maxValue(9_223_372_036_854_775_807n)) in Valibot, representing 64-bit integer limits.
Valibot schema for pg.point() and pg.geometry() with mode tuple
pg.geometry({ type: 'point', mode: 'tuple' }) and pg.point({ mode: 'tuple' }) map to tuple([number(), number()]) in Valibot.
Valibot schema for pg.point() and pg.geometry() with mode xy
pg.geometry({ type: 'point', mode: 'xy' }) and pg.point({ mode: 'xy' }) map to object({ x: number(), y: number() }) in Valibot.
Valibot schema for pg.halfvec() and pg.vector()
pg.halfvec({ dimensions: ... }) and pg.vector({ dimensions: ... }) map to pipe(array(number()), length(dimensions)) in Valibot.
Valibot schema for pg.line() with mode abc
pg.line({ mode: 'abc' }) maps to object({ a: number(), b: number(), c: number() }) in Valibot.
Valibot schema for pg.line() with mode tuple
pg.line({ mode: 'tuple' }) maps to tuple([number(), number(), number()]) in Valibot.
Valibot schema for pg.json() and pg.jsonb()
pg.json() and pg.jsonb() map to union([union([string(), number(), boolean(), null_()]), array(any()), record(string(), any())]) in Valibot.
Valibot schema for array types
pg.dataType().array(...) maps to pipe(array(baseDataTypeSchema), length(size)) in Valibot.
Valibot schema for pg.bytea()
pg.bytea() maps to custom<Buffer>((v) => v instanceof Buffer) in Valibot.
Example createSelectSchema with Valibot refinements
import { pgTable, text, integer, json } from 'drizzle-orm/pg-core';
import { createSelectSchema } from 'drizzle-orm/valibot';
import { parse, pipe, maxLength, object, string } from 'valibot';
const users = pgTable('users', {
id: integer().generatedAlwaysAsIdentity().primaryKey(),
name: text().notNull(),
bio: text(),
preferences: json()
});
const userSelectSchema = createSelectSchema(users, {
name: (schema) => pipe(schema, maxLength(20)),
bio: (schema) => pipe(schema, maxLength(1000)),
preferences: object({ theme: string() })
});
const parsed: {
id: number;
name: string;
bio: string | null;
preferences: {
theme: string;
};
} = parse(userSelectSchema, ...);
Example createSelectSchema from Drizzle table
import { pgTable, text, integer } from 'drizzle-orm/pg-core';
import { createSelectSchema } from 'drizzle-orm/valibot';
import { parse } from 'valibot';
const users = pgTable('users', {
id: integer().generatedAlwaysAsIdentity().primaryKey(),
name: text().notNull(),
age: integer().notNull()
});
const userSelectSchema = createSelectSchema(users);
const rows = await db.select({ id: users.id, name: users.name }).from(users).limit(1);
const parsed: { id: number; name: string; age: number } = parse(userSelectSchema, rows[0]); // Error: `age` is not returned in the above query
const rows = await db.select().from(users).limit(1);
const parsed: { id: number; name: string; age: number } = parse(userSelectSchema, rows[0]); // Will parse successfully
Example createInsertSchema from Drizzle table
import { pgTable, text, integer } from 'drizzle-orm/pg-core';
import { createInsertSchema } from 'drizzle-orm/valibot';
import { parse } from 'valibot';
const users = pgTable('users', {
id: integer().generatedAlwaysAsIdentity().primaryKey(),
name: text().notNull(),
age: integer().notNull()
});
const userInsertSchema = createInsertSchema(users);
const user = { name: 'John' };
const parsed: { name: string, age: number } = parse(userInsertSchema, user); // Error: `age` is not defined
const user = { name: 'Jane', age: 30 };
const parsed: { name: string, age: number } = parse(userInsertSchema, user); // Will parse successfully
await db.insert(users).values(parsed);
Example createUpdateSchema from Drizzle table
import { pgTable, text, integer } from 'drizzle-orm/pg-core';
import { createUpdateSchema } from 'drizzle-orm/valibot';
import { parse } from 'valibot';
const users = pgTable('users', {
id: integer().generatedAlwaysAsIdentity().primaryKey(),
name: text().notNull(),
age: integer().notNull()
});
const userUpdateSchema = createUpdateSchema(users);
const user = { age: 35 };
const parsed: { name?: string | undefined, age?: number | undefined } = parse(userUpdateSchema, user); // Will parse successfully
await db.update(users).set(parsed).where(eq(users.name, 'Jane'));
Example createSelectSchema with pgView and pgEnum
import { pgEnum, pgView } from 'drizzle-orm/pg-core';
import { gt } from 'drizzle-orm';
import { createSelectSchema } from 'drizzle-orm/valibot';
import { parse } from 'valibot';
const roles = pgEnum('roles', ['admin', 'basic']);
const rolesSchema = createSelectSchema(roles);
const parsed: 'admin' | 'basic' = parse(rolesSchema, ...);
const usersView = pgView('users_view').as((qb) => qb.select().from(users).where(gt(users.age, 18)));
const usersViewSchema = createSelectSchema(usersView);
const parsed: { id: number; name: string; age: number } = parse(usersViewSchema, ...);