Starting from drizzle-orm@1.0.0-beta.15, drizzle-zod has been deprecated in favor of first-class schema generation support within Drizzle ORM itself
You can still use drizzle-zod package but all new update will be added to Drizzle ORM directly
Starting from drizzle-orm@1.0.0-beta.15, drizzle-zod has been deprecated in favor of first-class schema generation support within Drizzle ORM itself
You can still use drizzle-zod package but all new update will be added to Drizzle ORM directly
npm i zod
Defines the shape of data queried from the database - can be used to validate API responses.
import { int, singlestoreTable, text } from 'drizzle-orm/singlestore-core';
import { createSelectSchema } from 'drizzle-orm/zod';
const users = singlestoreTable('users', {
id: int().primaryKey().autoincrement(),
name: text().notNull(),
age: int().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 } = userSelectSchema.parse(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 } = userSelectSchema.parse(rows[0]); // Will parse successfullyColumn enums are supported through the SingleStore table schema and can be validated with the generated table schemas.
Defines the shape of data to be inserted into the database - can be used to validate API requests.
import { int, singlestoreTable, text } from 'drizzle-orm/singlestore-core';
import { createInsertSchema } from 'drizzle-orm/zod';
const users = singlestoreTable('users', {
id: int().primaryKey().autoincrement(),
name: text().notNull(),
age: int().notNull()
});
const userInsertSchema = createInsertSchema(users);
const user = { name: 'John' };
const parsed: { name: string, age: number } = userInsertSchema.parse(user); // Error: `age` is not defined
const user = { name: 'Jane', age: 30 };
const parsed: { name: string, age: number } = userInsertSchema.parse(user); // Will parse successfully
await db.insert(users).values(parsed);Defines the shape of data to be updated in the database - can be used to validate API requests.
import { int, singlestoreTable, text } from 'drizzle-orm/singlestore-core';
import { createUpdateSchema } from 'drizzle-orm/zod';
const users = singlestoreTable('users', {
id: int().primaryKey().autoincrement(),
name: text().notNull(),
age: int().notNull()
});
const userUpdateSchema = createUpdateSchema(users);
const user = { id: 5, name: 'John' };
const parsed: { name?: string | undefined, age?: number | undefined } = userUpdateSchema.parse(user); // Error: `id` is a generated column, it can't be updated
const user = { age: 35 };
const parsed: { name?: string | undefined, age?: number | undefined } = userUpdateSchema.parse(user); // Will parse successfully
await db.update(users).set(parsed).where(eq(users.name, 'Jane'));Each create schema function accepts an additional optional parameter that you can used to extend, modify or completely overwite a field’s schema. Defining a callback function will extend or modify while providing a Zod schema will overwrite it.
import { int, json, singlestoreTable, text } from 'drizzle-orm/singlestore-core';
import { createSelectSchema } from 'drizzle-orm/zod';
import { z } from 'zod/v4';
const users = singlestoreTable('users', {
id: int().primaryKey(),
name: text().notNull(),
bio: text(),
preferences: json()
});
const userSelectSchema = createSelectSchema(users, {
name: (schema) => schema.max(20), // Extends schema
bio: (schema) => schema.max(1000), // Extends schema before becoming nullable/optional
preferences: z.object({ theme: z.string() }) // Overwrites the field, including its nullability
});
const parsed: {
id: number;
name: string,
bio?: string | undefined;
preferences: {
theme: string;
};
} = userSelectSchema.parse(...);For more advanced use cases, you can use the createSchemaFactory function.
Use case: Using an extended Zod instance
import { int, singlestoreTable, text } from 'drizzle-orm/singlestore-core';
import { createSchemaFactory } from 'drizzle-orm/zod';
import { z } from '@hono/zod-openapi'; // Extended Zod instance
const users = singlestoreTable('users', {
id: int().primaryKey().autoincrement(),
name: text().notNull(),
age: int().notNull()
});
const { createInsertSchema } = createSchemaFactory({ zodInstance: z });
const userInsertSchema = createInsertSchema(users, {
// We can now use the extended instance
name: (schema) => schema.openapi({ example: 'John' })
});Use case: Type coercion
import { singlestoreTable, timestamp } from 'drizzle-orm/singlestore-core';
import { createSchemaFactory } from 'drizzle-orm/zod';
import { z } from 'zod/v4';
const users = singlestoreTable('users', {
...,
createdAt: timestamp().notNull()
});
const { createInsertSchema } = createSchemaFactory({
// This configuration will only coerce dates. Set `coerce` to `true` to coerce all data types or specify others
coerce: {
date: true
}
});
const userInsertSchema = createInsertSchema(users);
// The above is the same as this:
const userInsertSchema = z.object({
...,
createdAt: z.coerce.date()
});singlestore.boolean();
// Schema
z.boolean();singlestore.date({ mode: 'date' });
singlestore.datetime({ mode: 'date' });
singlestore.timestamp({ mode: 'date' });
// Schema
z.date();singlestore.binary();
singlestore.date({ mode: 'string' });
singlestore.datetime({ mode: 'string' });
singlestore.decimal();
singlestore.time();
singlestore.timestamp({ mode: 'string' });
singlestore.varbinary();
// Schema
z.string();singlestore.char({ length: ... });
// Schema
z.string().length(length);singlestore.varchar({ length: ... });
// Schema
z.string().max(length);singlestore.text();
// Schema
z.string().max(65_535); // unsigned 16-bit integer limitsinglestore.text({ enum: ... });
singlestore.char({ enum: ... });
singlestore.varchar({ enum: ... });
singlestore.singlestoreEnum(..., ...);
// Schema
z.enum(enum);singlestore.tinyint();
// Schema
z.number().min(-128).max(127).int(); // 8-bit integer lower and upper limitsinglestore.tinyint({ unsigned: true });
// Schema
z.number().min(0).max(255).int(); // unsigned 8-bit integer lower and upper limitsinglestore.smallint();
// Schema
z.number().min(-32_768).max(32_767).int(); // 16-bit integer lower and upper limitsinglestore.smallint({ unsigned: true });
// Schema
z.number().min(0).max(65_535).int(); // unsigned 16-bit integer lower and upper limitsinglestore.float();
// Schema
z.number().min(-8_388_608).max(8_388_607); // 24-bit integer lower and upper limitsinglestore.mediumint();
// Schema
z.number().min(-8_388_608).max(8_388_607).int(); // 24-bit integer lower and upper limitsinglestore.float({ unsigned: true });
// Schema
z.number().min(0).max(16_777_215); // unsigned 24-bit integer lower and upper limitsinglestore.mediumint({ unsigned: true });
// Schema
z.number().min(0).max(16_777_215).int(); // unsigned 24-bit integer lower and upper limitsinglestore.int();
// Schema
z.number().min(-2_147_483_648).max(2_147_483_647).int(); // 32-bit integer lower and upper limitsinglestore.int({ unsigned: true });
// Schema
z.number().min(0).max(4_294_967_295).int(); // unsgined 32-bit integer lower and upper limitsinglestore.double();
singlestore.real();
// Schema
z.number().min(-140_737_488_355_328).max(140_737_488_355_327); // 48-bit integer lower and upper limitsinglestore.double({ unsigned: true });
// Schema
z.number().min(0).max(281_474_976_710_655); // unsigned 48-bit integer lower and upper limitsinglestore.bigint({ mode: 'number' });
// Schema
z.number().min(-9_007_199_254_740_991).max(9_007_199_254_740_991).int(); // Javascript min. and max. safe integerssinglestore.serial();
// Schema
z.number().min(0).max(9_007_199_254_740_991).int(); // Javascript max. safe integersinglestore.bigint({ mode: 'bigint' });
// Schema
z.bigint().min(-9_223_372_036_854_775_808n).max(9_223_372_036_854_775_807n); // 64-bit integer lower and upper limitsinglestore.bigint({ mode: 'bigint', unsigned: true });
// Schema
z.bigint().min(0).max(18_446_744_073_709_551_615n); // unsigned 64-bit integer lower and upper limitsinglestore.year();
// Schema
z.number().min(1_901).max(2_155).int();singlestore.json();
// Schema
z.union([z.union([z.string(), z.number(), z.boolean(), z.null()]), z.record(z.any()), z.array(z.any())]);