SQL schema declaration

You can declare your SQL schema directly in TypeScript either in a single schema.ts file, or you can spread them around — whichever you prefer, all the freedom!

1 File
Separate Files
Separate Folders

Everything in 1 file:

📦 <project root>
└ 📂 src
└ 📂 db
   └ 📜 schema.ts

You can declare tables, indexes and constraints, foreign keys and enums.

⚠️

Pay attention to the mandatory export keyword, if you’re using drizzle-kit SQL migrations generator.

PostgreSQL
MySQL
SQLite
import { integer, pgEnum, pgTable, serial, uniqueIndex, varchar } from 'drizzle-orm/pg-core';

// declaring enum in database
export const popularityEnum = pgEnum('popularity', ['unknown', 'known', 'popular']);

export const countries = pgTable('countries', {
  id: serial('id').primaryKey(),
  name: varchar('name', { length: 256 }),
}, (countries) => {
  return {
    nameIndex: uniqueIndex('name_idx').on(countries.name),
  }
});

export const cities = pgTable('cities', {
  id: serial('id').primaryKey(),
  name: varchar('name', { length: 256 }),
  countryId: integer('country_id').references(() => countries.id),
  popularity: popularityEnum('popularity'),
});

Database and table explicit entity types:

import { pgTable, serial, text, varchar } from 'drizzle-orm/pg-core';
import { drizzle } from 'drizzle-orm/node-postgres';

export const users = pgTable('users', {
  id: serial('id').primaryKey(),
  fullName: text('full_name'),
  phone: varchar('phone', { length: 256 }),
});

export type User = typeof users.$inferSelect; // return type when queried
export type NewUser = typeof users.$inferInsert; // insert type
...

const db = drizzle(...);

const result: User[] = await db.select().from(users);

export async function insertUser(user: NewUser): Promise<User[]> {
  return db.insert(users).values(user).returning();
}

Check out all supported PostgreSQL column types here.