### Equivalent pgPolicy setup for crudPolicy Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-kit/0.27.0.md Shows the equivalent manual `pgPolicy` setup for the `crudPolicy` example. This illustrates the underlying policy definitions for insert, update, delete, and select operations. ```typescript import { sql } from 'drizzle-orm'; import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core'; export const admin = pgRole('admin'); export const users = pgTable('users', { id: integer(), }, (t) => [ pgPolicy(`crud-${admin.name}-policy-insert`, { for: 'insert', to: admin, withCheck: sql`false`, }), pgPolicy(`crud-${admin.name}-policy-update`, { for: 'update', to: admin, using: sql`false`, withCheck: sql`false`, }), pgPolicy(`crud-${admin.name}-policy-delete`, { for: 'delete', to: admin, using: sql`false`, }), pgPolicy(`crud-${admin.name}-policy-select`, { for: 'select', to: admin, using: sql`true`, }), ]); ``` -------------------------------- ### Drizzle ORM Quick Start with SQLite Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/README.md A basic example demonstrating schema definition, database connection using better-sqlite3, and a simple select query. ```typescript import { sqliteTable, text, integer, } from 'drizzle-orm/sqlite-core'; import { drizzle } from 'drizzle-orm/better-sqlite3'; import Database from 'better-sqlite3'; const users = sqliteTable('users', { id: integer('id').primaryKey(), // 'id' is the column name fullName: text('full_name'), }) const sqlite = new Database('sqlite.db'); const db = drizzle(sqlite); const allUsers = db.select().from(users).all(); ``` -------------------------------- ### Custom Cache Implementation Example (NodeKV) Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-orm/src/cache/readme.md An example of a custom cache implementation using Keyv for storage. This class demonstrates how to define caching strategies, handle cache retrieval (`get`), storage (`put`), and invalidation on mutations (`onMutate`). It supports 'explicit' or 'all' caching strategies and tracks table usage for invalidation. ```typescript import Keyv from 'keyv'; export class TestGlobalCache extends Cache { private globalTtl: number = 1000; // This object will be used to store which query keys were used // for a specific table, so we can later use it for invalidation. private usedTablesPerKey: Record = {}; constructor(private kv: Keyv = new Keyv()) { super(); } // For the strategy, we have two options: // - 'explicit': The cache is used only when .$withCache() is added to a query. // - 'all': All queries are cached globally. // The default behavior is 'explicit'. override strategy(): 'explicit' | 'all' { return 'all'; } // This function accepts query and parameters that cached into key param, // allowing you to retrieve response values for this query from the cache. override async get(key: string): Promise { const res = await this.kv.get(key) ?? undefined; return res; } // This function accepts several options to define how cached data will be stored: // - 'key': A hashed query and parameters. // - 'response': An array of values returned by Drizzle from the database. // - 'tables': An array of tables involved in the select queries. This information is needed for cache invalidation. // // For example, if a query uses the "users" and "posts" tables, you can store this information. Later, when the app executes // any mutation statements on these tables, you can remove the corresponding key from the cache. // If you're okay with eventual consistency for your queries, you can skip this option. override async put(key: string, response: any, tables: string[], config?: CacheConfig): Promise { await this.kv.set(key, response, config ? config.ex : this.globalTtl); for (const table of tables) { const keys = this.usedTablesPerKey[table]; if (keys === undefined) { this.usedTablesPerKey[table] = [key]; } else { keys.push(key); } } } // This function is called when insert, update, or delete statements are executed. // You can either skip this step or invalidate queries that used the affected tables. // // The function receives an object with two keys: // - 'tags': Used for queries labeled with a specific tag, allowing you to invalidate by that tag. // - 'tables': The actual tables affected by the insert, update, or delete statements, // helping you track which tables have changed since the last cache update. override async onMutate(params: { tags: string | string[], tables: string | string[] | Table | Table[]}): Promise { const tagsArray = params.tags ? Array.isArray(params.tags) ? params.tags : [params.tags] : []; const tablesArray = params.tables ? Array.isArray(params.tables) ? params.tables : [params.tables] : []; const keysToDelete = new Set(); for (const table of tablesArray) { const tableName = is(table, Table) ? getTableName(table) : table as string; const keys = this.usedTablesPerKey[tableName] ?? []; for (const key of keys) keysToDelete.add(key); } if (keysToDelete.size > 0 || tagsArray.length > 0) { for (const tag of tagsArray) { await this.kv.delete(tag); } for (const key of keysToDelete) { await this.kv.delete(key); for (const table of tablesArray) { const tableName = is(table, Table) ? getTableName(table) : table as string; this.usedTablesPerKey[tableName] = []; } } } } } ``` -------------------------------- ### Basic Data Seeding with Drizzle ORM Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-seed/README.md This example demonstrates the basic usage of `drizzle-seed` to populate a 'users' table with 10 entities. Ensure `drizzle-orm@0.36.4` or higher is installed. ```typescript import { pgTable, integer, text } from "drizzle-orm/pg-core"; import { drizzle } from "drizzle-orm/node-postgres"; import { seed } from "drizzle-seed"; const users = pgTable("users", { id: integer().primaryKey(), name: text().notNull(), }); async function main() { const db = drizzle(process.env.DATABASE_URL!); await seed(db, { users }); } main(); ``` -------------------------------- ### Example Commit Message Source: https://github.com/replit/drizzle-orm/blob/main/CONTRIBUTING.md An example illustrating the correct format for a commit message. ```markdown Add groupBy error message In specific case, groupBy was responding with unreadable error ... ``` -------------------------------- ### Install Babel Plugin for Inline Imports Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.2.md Install the babel-plugin-inline-import package to support inline SQL file imports. ```bash npm install babel-plugin-inline-import ``` -------------------------------- ### Install Latest @libsql/client Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-kit/0.25.0.md Use this command to install the latest version of the @libsql/client package, which is required for the migrate function with Drizzle ORM and Turso. ```bash npm i @libsql/client@latest ``` -------------------------------- ### Install Node.js using NVM Source: https://github.com/replit/drizzle-orm/blob/main/CONTRIBUTING.md Installs Node.js version 18.13.0 using NVM. Ensure NVM is installed first. ```bash curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash nvm install 18.13.0 nvm use 18.13.0 ``` -------------------------------- ### Install Drizzle ORM and Xata Client Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.30.4.md Install the necessary packages for Drizzle ORM and the Xata client using pnpm. ```bash pnpm add drizzle-orm @xata.io/client ``` -------------------------------- ### Install Drizzle ORM and better-sqlite3 Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/README.md Install the core Drizzle ORM package along with the better-sqlite3 driver. Optionally, install drizzle-kit for automatic migrations. ```bash npm install drizzle-orm better-sqlite3 ## opt-in automatic migrations generator npm install -D drizzle-kit ``` -------------------------------- ### Basic Database Seeding with Drizzle ORM Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-seed/0.1.1.md Use this snippet to perform basic seeding of your database tables. Ensure you have `drizzle-orm@0.36.4` or higher installed. This example creates 10 users with random names and IDs. ```typescript import { pgTable, integer, text } from "drizzle-orm/pg-core"; import { drizzle } from "drizzle-orm/node-postgres"; import { seed } from "drizzle-seed"; const users = pgTable("users", { id: integer().primaryKey(), name: text().notNull(), }); async function main() { const db = drizzle(process.env.DATABASE_URL!); await seed(db, { users }); } main(); ``` -------------------------------- ### Implement Custom Cache with Keyv for Drizzle ORM Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.44.0.md Create a custom cache implementation extending Drizzle's Cache class, using Keyv for storage. This example demonstrates 'all' caching strategy and outlines methods for get, put, and onMutate operations. ```typescript import Keyv from "keyv"; export class TestGlobalCache extends Cache { private globalTtl: number = 1000; // This object will be used to store which query keys were used // for a specific table, so we can later use it for invalidation. private usedTablesPerKey: Record = {}; constructor(private kv: Keyv = new Keyv()) { super(); } // For the strategy, we have two options: // - 'explicit': The cache is used only when .$withCache() is added to a query. // - 'all': All queries are cached globally. // The default behavior is 'explicit'. override strategy(): "explicit" | "all" { return "all"; } // This function accepts query and parameters that cached into key param, // allowing you to retrieve response values for this query from the cache. override async get(key: string): Promise { ... } // This function accepts several options to define how cached data will be stored: // - 'key': A hashed query and parameters. // - 'response': An array of values returned by Drizzle from the database. // - 'tables': An array of tables involved in the select queries. This information is needed for cache invalidation. // // For example, if a query uses the "users" and "posts" tables, you can store this information. Later, when the app executes // any mutation statements on these tables, you can remove the corresponding key from the cache. // If you're okay with eventual consistency for your queries, you can skip this option. override async put( key: string, response: any, tables: string[], config?: CacheConfig, ): Promise { ... } // This function is called when insert, update, or delete statements are executed. // You can either skip this step or invalidate queries that used the affected tables. // // The function receives an object with two keys: // - 'tags': Used for queries labeled with a specific tag, allowing you to invalidate by that tag. // - 'tables': The actual tables affected by the insert, update, or delete statements, // helping you track which tables have changed since the last cache update. override async onMutate(params: { tags: string | string[]; tables: string | string[] | Table | Table[]; }): Promise { ... } } ``` -------------------------------- ### Install ESLint and Drizzle Plugin Source: https://github.com/replit/drizzle-orm/blob/main/eslint-plugin-drizzle/readme.md Install the necessary ESLint and eslint-plugin-drizzle packages using your preferred package manager. ```sh [ npm | yarn | pnpm | bun ] install eslint eslint-plugin-drizzle ``` -------------------------------- ### Install Drizzle ORM and Postgres.js Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-orm/src/postgres-js/README.md Install the necessary Drizzle ORM packages and the Postgres.js driver using npm, yarn, or pnpm. ```bash # npm npm i drizzle-orm postgres npm i -D drizzle-kit # yarn yarn add drizzle-orm postgres yarn add -D drizzle-kit # pnpm pnpm add drizzle-orm postgres pnpm add -D drizzle-kit ``` -------------------------------- ### Install Drizzle Kit CLI Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-kit/README.md Install Drizzle Kit as a development dependency in your project. ```shell npm install -D drizzle-kit ``` -------------------------------- ### Install TypeScript ESLint Support Source: https://github.com/replit/drizzle-orm/blob/main/eslint-plugin-drizzle/readme.md Install the TypeScript ESLint packages to enable type checking and linting for TypeScript projects. ```sh [ npm | yarn | pnpm | bun ] install @typescript-eslint/eslint-plugin @typescript-eslint/parser ``` -------------------------------- ### Connect to Gel Database with Drizzle Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.40.0.md Connect to a Gel database using Drizzle ORM and the gel-js client. Ensure the 'gel' package is installed. This example demonstrates basic connection and executing a simple query. ```typescript // Make sure to install the 'gel' package import { drizzle } from "drizzle-orm/gel"; import { createClient } from "gel"; const gelClient = createClient(); const db = drizzle({ client: gelClient }); const result = await db.execute('select 1'); ``` -------------------------------- ### Install pnpm Package Manager Source: https://github.com/replit/drizzle-orm/blob/main/CONTRIBUTING.md Installs the pnpm package manager globally using npm. ```bash npm install -g pnpm ``` -------------------------------- ### PostgreSQL/SQLite UPDATE FROM Example Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.36.3.md Demonstrates updating a table using data from another table in PostgreSQL and SQLite. Ensure the 'from' table is correctly specified. ```typescript await db .update(users) .set({ cityId: cities.id }) .from(cities) .where(and(eq(cities.name, 'Seattle'), eq(users.name, 'John'))) ``` ```sql update "users" set "city_id" = "cities"."id" from "cities" where ("cities"."name" = $1 and "users"."name" = $2) -- params: [ 'Seattle', 'John' ] ``` -------------------------------- ### Build Drizzle ORM Project Source: https://github.com/replit/drizzle-orm/blob/main/CONTRIBUTING.md Installs project dependencies using pnpm and builds the entire monorepo. Run from the root folder. ```bash pnpm install && pnpm build ``` -------------------------------- ### Reset and Seed Database Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-seed/README.md This example shows how to reset your database and seed it with new values, commonly used in test suites. Ensure the correct schema file path is provided. ```typescript // path to a file with schema you want to reset import * as schema from "./schema.ts"; import { reset } from "drizzle-seed"; async function main() { const db = drizzle(process.env.DATABASE_URL!); await reset(db, schema); } main(); ``` -------------------------------- ### Min Aggregate Function Example Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.1.md Shows the usage of `min()` and its `sql` template tag equivalent. Remember to use `.groupBy` if selecting other columns. ```typescript await db.select({ value: min(users.id) }).from(users); // It's equivalent to writing await db.select({ value: sql`min(${users.id})`.mapWith(users.id) }).from(users); ``` -------------------------------- ### Install ESLint Drizzle Plugin Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.1.md Commands to install the ESLint Drizzle plugin and necessary TypeScript support packages. These packages help with type checking and IDE integration. ```sh [ npm | yarn | pnpm | bun ] install eslint eslint-plugin-drizzle ``` ```sh [ npm | yarn | pnpm | bun ] install @typescript-eslint/eslint-plugin @typescript-eslint/parser ``` -------------------------------- ### Sum Aggregate Function Example Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.1.md Shows how to use the `sum()` helper function and its equivalent using the `sql` template tag. Use `.groupBy` if selecting other columns. ```typescript await db.select({ value: sum(users.id) }).from(users); // It's equivalent to writing await db.select({ value: sql`sum(${users.id})`.mapWith(String) }).from(users); ``` -------------------------------- ### Install ESLint Drizzle Plugin Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.2.md Install the ESLint Drizzle plugin version 0.2.3 using npm. ```bash npm i eslint-plugin-drizzle@0.2.3 ``` -------------------------------- ### Many-to-one Join Example Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/README.md Demonstrates a many-to-one relationship between cities and users, joining them to retrieve city and user information. ```typescript import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core'; import { drizzle } from 'drizzle-orm/better-sqlite3'; const cities = sqliteTable('cities', { id: integer('id').primaryKey(), name: text('name'), }); const users = sqliteTable('users', { id: integer('id').primaryKey(), name: text('name'), cityId: integer('city_id').references(() => cities.id) }); const db = drizzle(sqlite); const result = db.select().from(cities).leftJoin(users, eq(cities.id, users.cityId)).all(); ``` -------------------------------- ### Install Expo SQLite Driver Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.2.md Install the Drizzle ORM and Expo SQLite packages for Expo development. ```bash npm install drizzle-orm expo-sqlite@next ``` -------------------------------- ### Generated SQL Migrations Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-kit/README.md Example SQL output generated by Drizzle Kit based on the provided schema. ```sql CREATE TABLE IF NOT EXISTS auth_otp ( "id" SERIAL PRIMARY KEY, "phone" character varying(256), "user_id" INT ); CREATE TABLE IF NOT EXISTS users ( "id" SERIAL PRIMARY KEY, "full_name" character varying(256) ); DO $$ BEGIN ALTER TABLE auth_otp ADD CONSTRAINT auth_otp_user_id_fkey FOREIGN KEY ("user_id") REFERENCES users(id); EXCEPTION WHEN duplicate_object THEN null; END $$; CREATE INDEX IF NOT EXISTS users_full_name_index ON users (full_name); ``` -------------------------------- ### Max Aggregate Function Example Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.1.md Demonstrates the `max()` helper function and its `sql` template tag equivalent. Use `.groupBy` when selecting other columns. ```typescript await db.select({ value: max(users.id) }).from(users); // It's equivalent to writing await db.select({ value: sql`max(${expression})`.mapWith(users.id) }).from(users); ``` -------------------------------- ### Example SQLite Table Schema Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-kit/0.25.0.md A sample SQLite table schema definition, illustrating column types and foreign key constraints. ```sql CREATE TABLE `users` ( `id` integer NOT NULL, `name` integer, `age` integer PRIMARY KEY NOT NULL FOREIGN KEY (`name`) REFERENCES `users1`("id") ON UPDATE no action ON DELETE no action ); ``` -------------------------------- ### Initialize Drizzle with PGlite Client Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.30.6.md Use this snippet to initialize an in-memory PGlite database and integrate it with Drizzle ORM. Ensure you have '@electric-sql/pglite' and 'drizzle-orm' installed. ```typescript import { PGlite } from '@electric-sql/pglite'; import { drizzle } from 'drizzle-orm/pglite'; // In-memory Postgres const client = new PGlite(); const db = drizzle(client); await db.select().from(users); ``` -------------------------------- ### Initialize Drizzle with Bun SQL Driver Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.39.0.md Use this snippet to initialize Drizzle ORM with the Bun SQL driver. Ensure you have Bun v1.2.0 or later installed. The `process.env.PG_DB_URL!` should be set to your PostgreSQL connection string. ```typescript import { drizzle } from 'drizzle-orm/bun-sql'; const db = drizzle(process.env.PG_DB_URL!); const result = await db.select().from(...); ``` -------------------------------- ### Count Aggregate Function Example Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.1.md Demonstrates how to use the `count()` helper function and its equivalent using the `sql` template tag. Remember to use `.groupBy` if selecting other columns. ```typescript await db.select({ value: count() }).from(users); await db.select({ value: count(users.id) }).from(users); // It's equivalent to writing await db.select({ value: sql`count('*'))`.mapWith(Number) }).from(users); await db.select({ value: sql`count(${users.id})`.mapWith(Number) }).from(users); ``` -------------------------------- ### Average Distinct Aggregate Function Example Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.1.md Demonstrates `avgDistinct()` and its `sql` template tag counterpart. Remember to use `.groupBy` if selecting other columns. ```typescript await db.select({ value: avgDistinct(users.id) }).from(users); // It's equivalent to writing await db.select({ value: sql`avg(distinct ${users.id})`.mapWith(String) }).from(users); ``` -------------------------------- ### Average Aggregate Function Example Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.1.md Illustrates the `avg()` helper function and its `sql` template tag equivalent. Use `.groupBy` when combining with other selected columns. ```typescript await db.select({ value: avg(users.id) }).from(users); // It's equivalent to writing await db.select({ value: sql`avg(${users.id})`.mapWith(String) }).from(users); ``` -------------------------------- ### Define User and City Tables Source: https://github.com/replit/drizzle-orm/blob/main/docs/joins.md Defines the 'users' and 'cities' tables with their respective columns and relationships. This setup is necessary before performing joins. ```typescript const users = pgTable('users', { id: serial('id').primaryKey(), firstName: text('first_name').notNull(), lastName: text('last_name'), cityId: int('city_id').references(() => cities.id), }); const cities = pgTable('cities', { id: serial('id').primaryKey(), name: text('name').notNull(), }); ``` -------------------------------- ### ESLint Drizzle Plugin Basic Configuration Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.1.md Example `.eslintrc.yml` configuration to enable the Drizzle ESLint plugin and specify rules like `enforce-delete-with-where` and `enforce-update-with-where`. ```yaml root: true parser: '@typescript-eslint/parser' parserOptions: project: './tsconfig.json' plugins: - drizzle rules: 'drizzle/enforce-delete-with-where': "error" 'drizzle/enforce-update-with-where': "error" ``` -------------------------------- ### Initialize Drizzle with Bun SQL Instance Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.39.0.md This example shows how to initialize Drizzle ORM using an existing Bun SQL instance. This approach is useful when you need more control over the SQL client configuration. The `process.env.PG_DB_URL!` should be set to your PostgreSQL connection string. ```typescript import { drizzle } from 'drizzle-orm/bun-sqlite'; import { SQL } from 'bun'; const client = new SQL(process.env.PG_DB_URL!); const db = drizzle({ client }); const result = await db.select().from(...); ``` -------------------------------- ### Implement PostgreSQL Proxy Driver Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.0.md Example of implementing a custom HTTP driver for PostgreSQL with Drizzle ORM. Requires implementing query and migration endpoints on a server. Ensure the REMOTE_DRIVER environment variable is set. ```typescript import axios from 'axios'; import { eq } from 'drizzle-orm/expressions'; import { drizzle } from 'drizzle-orm/pg-proxy'; import { migrate } from 'drizzle-orm/pg-proxy/migrator'; import { cities, users } from './schema'; async function main() { const db = drizzle(async (sql, params, method) => { try { const rows = await axios.post(`${process.env.REMOTE_DRIVER}/query`, { sql, params, method }); return { rows: rows.data }; } catch (e: any) { console.error('Error from pg proxy server:', e.response.data); return { rows: [] }; } }); await migrate(db, async (queries) => { try { await axios.post(`${process.env.REMOTE_DRIVER}/query`, { queries }); } catch (e) { console.log(e); throw new Error('Proxy server cannot run migrations'); } }, { migrationsFolder: 'drizzle' }); const insertedCity = await db.insert(cities).values({ id: 1, name: 'name' }).returning(); const insertedUser = await db.insert(users).values({ id: 1, name: 'name', email: 'email', cityId: 1 }); const usersToCityResponse = await db.select().from(users).leftJoin(cities, eq(users.cityId, cities.id)); } ``` -------------------------------- ### Connect to Xata with Drizzle ORM Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.30.4.md Initialize the Xata client and establish a connection with Drizzle ORM using the xata-http driver. This example assumes you have a generated Xata client. ```typescript import { drizzle } from 'drizzle-orm/xata-http'; import { getXataClient } from './xata'; // Generated client const xata = getXataClient(); const db = drizzle(xata); const result = await db.select().from(...); ``` -------------------------------- ### Connect to Vercel Postgres with Drizzle ORM Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.25.4.md Import necessary modules and initialize the Drizzle ORM client with the Vercel Postgres SQL function. This setup is required before performing any database operations. ```typescript import { drizzle } from 'drizzle-orm/vercel-postgres'; import { sql } from "@vercel/postgres"; const db = drizzle(sql); db.select(...) ``` -------------------------------- ### Connect using a Custom Proxy HTTP driver Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/README.md Example of connecting to a SQLite database via a custom HTTP proxy driver. This allows for custom backend implementations. ```typescript // Custom Proxy HTTP driver const db = drizzle(async (sql, params, method) => { try { const rows = await axios.post('http://localhost:3000/query', { sql, params, method }); return { rows: rows.data }; } catch (e: any) { console.error('Error from sqlite proxy server: ', e.response.data) return { rows: [] }; } }); // More example for proxy: https://github.com/drizzle-team/drizzle-orm/tree/main/examples/sqlite-proxy ``` -------------------------------- ### Get View Name using getViewName Util Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.39.0.md This example demonstrates how to use the `getViewName` utility function from `drizzle-orm/sql` to retrieve the name of a Drizzle ORM view. This is useful for introspection and dynamic SQL generation. ```typescript import { getViewName } from 'drizzle-orm/sql' export const user = pgTable("user", { id: serial(), name: text(), email: text(), }); export const userView = pgView("user_view").as((qb) => qb.select().from(user)); const viewName = getViewName(userView) ``` -------------------------------- ### Configuring Drizzle Kit with PostGIS Extension Filter Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.31.0.md Provides an example of configuring `drizzle-kit` to automatically filter out tables created by the PostGIS extension during introspection or diff operations using `extensionsFilters`. ```typescript import { defineConfig } from 'drizzle-kit' export default defaultConfig({ dialect: "postgresql", extensionsFilters: ["postgis"], }) ``` -------------------------------- ### Implement PostgreSQL Identity Columns with Drizzle ORM Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.32.0-beta.md Use Drizzle ORM to define PostgreSQL identity columns, the recommended alternative to the outdated `serial` type. This example shows how to set a starting value for the identity column. ```typescript import { pgTable, integer, text } from 'drizzle-orm/pg-core' export const ingredients = pgTable("ingredients", { id: integer("id").primaryKey().generatedAlwaysAsIdentity({ startWith: 1000 }), name: text("name").notNull(), description: text("description"), }); ``` -------------------------------- ### Get Table Columns Map Source: https://github.com/replit/drizzle-orm/blob/main/docs/table-introspect-api.md Utilize `getTableColumns` to obtain a map of all columns defined for a Drizzle ORM table. This is useful for accessing column definitions programmatically. The example shows retrieving columns for a table with 'id' and 'name' fields. ```typescript import { pgTable, getTableColumns } from 'drizzle-orm/pg-core'; const table = pgTable('table', { id: integer('id').primaryKey(), name: text('name'), }); const columns/*: { id: ..., name: ... } */ = getTableColumns(table); ``` -------------------------------- ### Connect to TiDB Cloud Serverless with Drizzle ORM Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.31.2.md Import necessary modules and establish a connection to TiDB Cloud Serverless using the provided URL. This setup is required before performing any database operations. ```typescript import { connect } from '@tidbcloud/serverless'; import { drizzle } from 'drizzle-orm/tidb-serverless'; const client = connect({ url: '...' }); const db = drizzle(client); await db.select().from(...); ``` -------------------------------- ### Setup Custom SQLite Proxy Driver with Drizzle ORM Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.17.4.md Use this custom proxy driver to implement custom logic for database calls. It's particularly useful for serverless applications. Ensure axios is installed for making HTTP requests. ```typescript import { drizzle } from 'drizzle-orm/node-postgres'; import axios from 'axios'; // Custom Proxy HTTP driver const db = drizzle(async (sql, params, method) => { try { const rows = await axios.post('http://localhost:3000/query', { sql, params, method }); return { rows: rows.data }; } catch (e: any) { console.error('Error from sqlite proxy server: ', e.response.data) return { rows: [] }; } }); ``` -------------------------------- ### Drizzle Kit Configuration with JavaScript Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.26.0.md Example of a Drizzle Kit configuration file using JavaScript syntax with JSDoc annotations. Replace placeholder values with your actual schema path, connection string, and output directory. ```javascript /** @type { import("drizzle-kit").Config } */ export default { schema: "", connectionString: "", out: "", breakpoints: true }; ``` -------------------------------- ### Login to npm Registry and Publish Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-kit/README.md Log in to the Replit-internal npm registry and publish the packed Drizzle Kit package. ```bash npm run login npm run publish ``` -------------------------------- ### Drizzle Kit Configuration with TypeScript Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.26.0.md Example of a Drizzle Kit configuration file using TypeScript syntax. Ensure to replace placeholder values with your actual schema path, connection string, and output directory. ```typescript import { Config } from "drizzle-kit"; export default { schema: "", connectionString: process.env.DB_URL, out: "", breakpoints: true } satisfies Config; ``` -------------------------------- ### Add Local Drizzle Kit Package Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-kit/README.md After building the Drizzle Kit, add it as a local file dependency to the 'repl-it-web' project. ```bash cd pkg/pid2/ pnpm add @drizzle-team/drizzle-kit@file:../../../drizzle-orm/drizzle-kit/dist ``` -------------------------------- ### Raw SQL for Left Join Source: https://github.com/replit/drizzle-orm/blob/main/docs/joins.md Illustrates the equivalent SQL query for selecting cities and their associated users using a left join. ```sql select cities.id as city_id, cities.name as city_name, users.id as user_id, users.first_name, users.last_name from cities left join users on users.city_id = cities.id ``` -------------------------------- ### Run Drizzle Kit Migration Generation Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-kit/README.md Execute the npm script to generate database migrations. ```bash npm run generate ``` -------------------------------- ### Many-to-many Join Example Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/README.md Illustrates a many-to-many relationship between users and chat groups, joined through a linking table. ```typescript const users = sqliteTable('users', { id: integer('id').primaryKey(), name: text('name'), }); const chatGroups = sqliteTable('chat_groups', { id: integer('id').primaryKey(), name: text('name'), }); const usersToChatGroups = sqliteTable('usersToChatGroups', { userId: integer('user_id').notNull().references(() => users.id), groupId: integer('group_id').notNull().references(() => chatGroups.id), }); ... // Assuming db is initialized // querying user group with id 1 and all the participants(users) db .select() .from(usersToChatGroups) .leftJoin(users, eq(usersToChatGroups.userId, users.id)) .leftJoin(chatGroups, eq(usersToChatGroups.groupId, chatGroups.id)) .where(eq(chatGroups.id, 1)) .all(); ``` -------------------------------- ### Drizzle Schema Definition Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-kit/README.md Example TypeScript schema definition using Drizzle ORM's pg-core for PostgreSQL. ```typescript // src/db/schema.ts import { integer, pgTable, serial, text, varchar } from "drizzle-orm/pg-core"; const users = pgTable("users", { id: serial("id").primaryKey(), fullName: varchar("full_name", { length: 256 }), }, (table) => ({ nameIdx: index("name_idx", table.fullName), }) ); export const authOtp = pgTable("auth_otp", { id: serial("id").primaryKey(), phone: varchar("phone", { length: 256 }), userId: integer("user_id").references(() => users.id), }); ``` -------------------------------- ### JSONB Value Mapping for PostgreSQL Source: https://github.com/replit/drizzle-orm/blob/main/docs/custom-types.md Example of overriding `mapToDriverValue` for a custom JSONB type to stringify the value before sending it to the database. ```typescript override mapToDriverValue(value: TData): string { return JSON.stringify(value); } ``` -------------------------------- ### Basic Usage of drizzle-seed Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.36.4.md Demonstrates how to seed a database with 10 users using the drizzle-seed package. Requires drizzle-orm@0.36.4 or higher. ```typescript import { pgTable, integer, text } from "drizzle-orm/pg-core"; import { drizzle } from "drizzle-orm/node-postgres"; import { seed } from "drizzle-seed"; const users = pgTable("users", { id: integer().primaryKey(), name: text().notNull(), }); async function main() { const db = drizzle(process.env.DATABASE_URL!); await seed(db, { users }); } main(); ``` -------------------------------- ### Drizzle Kit PR Title Example Source: https://github.com/replit/drizzle-orm/blob/main/CONTRIBUTING.md Follow this pattern for Drizzle Kit PR titles, specifying the dialect and subject. ```text [Pg-kit] Add PostGIS extension support ``` -------------------------------- ### Initialize Drizzle with Existing Client (Deprecated) Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.35.0.md Demonstrates the deprecated method of initializing Drizzle with an existing pg Pool client. The new API is recommended. ```typescript import { drizzle } from "drizzle-orm/node-postgres"; import { Pool } from "pg"; const client = new Pool({ connectionString: process.env.DATABASE_URL }); const db = drizzle(client); // deprecated but available // new version const db = drizzle({ client: client, }); ``` -------------------------------- ### Drizzle ORM PR Title Example Source: https://github.com/replit/drizzle-orm/blob/main/CONTRIBUTING.md Follow this pattern for PR titles to clearly indicate the dialect and subject of your changes. ```text [Pg] Add PostGIS extension support ``` -------------------------------- ### Index Creation SQL Comparison Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.31.0.md Illustrates the difference in SQL generated for expression-based unique indexes before and after an update, showing improved handling of expressions. ```sql -- before CREATE UNIQUE INDEX `emailUniqueIndex` ON `users` (`lower("users"."email")`); -- now CREATE UNIQUE INDEX `emailUniqueIndex` ON `users` (lower("email")); ``` -------------------------------- ### Example: Using Supabase Service Role for Insert Policy Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-kit/0.27.0.md Demonstrates how to use the predefined `serviceRole` from Drizzle ORM's Supabase integration to define a Row Level Security (RLS) policy for inserts on a 'users' table. ```typescript import { sql } from 'drizzle-orm'; import { serviceRole } from 'drizzle-orm/supabase'; import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core'; export const admin = pgRole('admin'); export const users = pgTable('users', { id: integer(), }, (t) => [ pgPolicy(`policy-insert`, { for: 'insert', to: serviceRole, withCheck: sql`false`, }), ]); ``` -------------------------------- ### Connect to PlanetScale Serverless with Drizzle ORM Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.17.5.md Establishes a connection to PlanetScale Serverless using the database.js driver and initializes Drizzle ORM. Ensure your database credentials are set as environment variables. ```typescript import { drizzle } from 'drizzle-orm/planetscale-serverless'; import { connect } from '@planetscale/database'; // create the connection const connection = connect({ host: process.env['DATABASE_HOST'], username: process.env['DATABASE_USERNAME'], password: process.env['DATABASE_PASSWORD'], }); const db = drizzle(connection); ``` -------------------------------- ### Seed with Specific Generator Version Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-seed/0.2.1.md Use the `version` option in the `seed` function to specify the generator version. This example uses version '2'. ```typescript await seed(db, schema, { version: '2' }); ``` -------------------------------- ### Build Drizzle Kit Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-kit/README.md After making changes to the Drizzle Kit source files, rebuild the package from the 'drizzle-kit' directory. ```bash pnpm build ``` -------------------------------- ### Using Prepared Statements with Placeholders Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-orm/src/sqlite-core/README.md Utilize prepared statements and placeholder APIs for faster query execution. Define queries with placeholders for dynamic values, which are then executed with specific parameters. ```typescript import { placeholder } from 'drizzle-orm'; const db = drizzle(...); const q = db.select().from(customers).prepare(); q.all() // SELECT * FROM customers const q = db.select().from(customers).where(eq(customers.id, placeholder('id'))).prepare() q.get({ id: 10 }) // SELECT * FROM customers WHERE id = 10 q.get({ id: 12 }) // SELECT * FROM customers WHERE id = 12 const q = db .select() .from(customers) .where(sql`lower(${customers.name}) like ${placeholder('name')}`) .prepare(); q.all({ name: '%an%' }) // SELECT * FROM customers WHERE name ilike '%an%' ``` -------------------------------- ### Sum Distinct Aggregate Function Example Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.1.md Illustrates `sumDistinct()` and its `sql` template tag equivalent. Ensure `.groupBy` is used when selecting other columns. ```typescript await db.select({ value: sumDistinct(users.id) }).from(users); // It's equivalent to writing await db.select({ value: sql`sum(distinct ${users.id})`.mapWith(String) }).from(users); ``` -------------------------------- ### Initialize Mock Drizzle Instance Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.35.0.md Creates a mock Drizzle instance without requiring a database driver, useful for type checking and testing without actual database calls. ```typescript const db = drizzle.mock() ``` -------------------------------- ### Initialize Drizzle with Default LibSQL Driver Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.35.3.md Use this for the default @libsql/client import. It automatically adapts to node or web environments based on your bundler's target or platform settings. ```typescript import { drizzle } from 'drizzle-orm/libsql'; const db = drizzle({ connection: { url: process.env.DATABASE_URL, authToken: process.env.DATABASE_AUTH_TOKEN }}); ``` -------------------------------- ### Count Distinct Aggregate Function Example Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.1.md Shows the usage of `countDistinct()` and its equivalent with the `sql` template tag. Ensure `.groupBy` is used when necessary. ```typescript await db.select({ value: countDistinct(users.id) }).from(users); // It's equivalent to writing await db.select({ value: sql`count(${users.id})`.mapWith(Number) }).from(users); ``` -------------------------------- ### Parse Data with Generated Valibot Schema Source: https://github.com/replit/drizzle-orm/blob/main/drizzle-valibot/README.md Use the generated Valibot schema to parse and validate data. This example demonstrates validating an object against the insertUserSchema. ```typescript import { pgEnum, pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core'; import { createInsertSchema, createSelectSchema, createUpdateSchema } from 'drizzle-valibot'; import { string, parse, number, pipe } from 'valibot'; const users = pgTable('users', { id: serial('id').primaryKey(), name: text('name').notNull(), email: text('email').notNull(), role: text('role', { enum: ['admin', 'user'] }).notNull(), createdAt: timestamp('created_at').notNull().defaultNow(), }); // Overriding the fields const insertUserSchema = createInsertSchema(users, { role: string(), }); // Usage const isUserValid = parse(insertUserSchema, { name: 'John Doe', email: 'johndoe@test.com', role: 'admin', }); ``` -------------------------------- ### Example: Referencing Supabase Auth Table and Authenticated Role Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-kit/0.27.0.md Shows how to define a 'profiles' table with a foreign key referencing Supabase's 'auth.users' table and applying a Row Level Security (RLS) 'select' policy using the predefined `authenticatedRole`. ```typescript import { foreignKey, pgPolicy, pgTable, text, uuid } from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm/sql"; import { authenticatedRole, authUsers } from "drizzle-orm/supabase"; export const profiles = pgTable( "profiles", { id: uuid().primaryKey().notNull(), email: text().notNull(), }, (table) => [ foreignKey({ columns: [table.id], // reference to the auth table from Supabase foreignColumns: [authUsers.id], name: "profiles_id_fk", }).onDelete("cascade"), pgPolicy("authenticated can view all profiles", { for: "select", // using predefined role from Supabase to: authenticatedRole, using: sql`true`, }), ] ); ``` -------------------------------- ### Initialize Drizzle with LibSQL Node Driver Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.35.3.md This module is specifically for Node.js environments and supports various connection protocols like :memory:, file, wss, http, and turso. ```typescript import { drizzle } from 'drizzle-orm/libsql/node'; const db = drizzle({ connection: { url: process.env.DATABASE_URL, authToken: process.env.DATABASE_AUTH_TOKEN }}); ``` -------------------------------- ### Usage Example for CITEXT Column Source: https://github.com/replit/drizzle-orm/blob/main/docs/custom-types.md Demonstrates how to declare a table with a `ciname` column using the `citext` data type. This column will perform case-insensitive comparisons. ```typescript const table = pgTable('table', { id: integer('id').primaryKey(), ciname: citext('ciname') }) ``` -------------------------------- ### Integer Value Mapping for PostgreSQL Source: https://github.com/replit/drizzle-orm/blob/main/docs/custom-types.md Example of overriding `mapFromDriverValue` for a custom integer type to parse string values into numbers when retrieving data from the database. ```typescript override mapFromDriverValue(value: number | string): number { if (typeof value === 'string') { return parseInt(value); } return value; } ``` -------------------------------- ### Drizzle Config File Setup (TypeScript) Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.26.0.md Configure your Drizzle ORM schema and database connection for the push feature. Ensure `schema` and `connectionString` are correctly set, potentially using environment variables for sensitive information. ```typescript import { Config } from "src"; export default { schema: "./schema.ts", connectionString: process.env.DB_URL, } satisfies Config; ``` -------------------------------- ### Example: enforce-update-with-where with drizzleObjectName Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.1.md Shows how specifying `drizzleObjectName` prevents the `enforce-update-with-where` rule from triggering on custom class `update` methods, while still enforcing it for `db.update()`. ```typescript class MyClass { public update() { return {} } } const myClassObj = new MyClass(); // ---> Will NOT be triggered by ESLint Rule myClassObj.update() const db = drizzle(...) // ---> Will be triggered by ESLint Rule db.update() ``` -------------------------------- ### Example: enforce-delete-with-where with drizzleObjectName Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.29.1.md Shows how specifying `drizzleObjectName` prevents the `enforce-delete-with-where` rule from triggering on custom class `delete` methods, while still enforcing it for `db.delete()`. ```typescript class MyClass { public delete() { return {} } } const myClassObj = new MyClass(); // ---> Will NOT be triggered by ESLint Rule myClassObj.delete() const db = drizzle(...) // ---> Will be triggered by ESLint Rule db.delete() ``` -------------------------------- ### Initialize Drizzle Database API (Node.js) Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.35.0.md Use this API to create driver clients for your Drizzle database connection. Supports direct URL or connection object. ```typescript import { drizzle } from "drizzle-orm/node-postgres"; const db = drizzle(process.env.DATABASE_URL); // or const db = drizzle({ connection: process.env.DATABASE_URL }); const db = drizzle({ connection: { user: "...", password: "...", host: "...", port: 4321, db: "...", }, }); // if you need to pass logger or schema const db = drizzle({ connection: process.env.DATABASE_URL, logger: true, schema: schema, }); ``` -------------------------------- ### PostgreSQL Array Operator with Subquery Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.28.6.md Example of using the `arrayContains` operator with a subquery in Drizzle ORM to check for array containment based on dynamic data. ```typescript const withSubQuery = await db.select({ id: posts.id }).from(posts) .where( arrayContains( posts.tags, db.select({ tags: posts.tags }).from(posts).where(eq(posts.id, 1)), ) ); ``` -------------------------------- ### Import Neon Identity Schema and Table Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.39.0.md This snippet shows how to import the `neon_identity` schema and the `users_sync` table directly from the `/neon` import path. This simplifies the process of accessing Neon-specific user synchronization tables. ```typescript // "drizzle-orm/neon" const neonIdentitySchema = pgSchema('neon_identity'); /** * Table schema of the `users_sync` table used by Neon Identity. * This table automatically synchronizes and stores user data from external authentication providers. * * @schema neon_identity * @table users_sync */ export const usersSync = neonIdentitySchema.table('users_sync', { rawJson: jsonb('raw_json').notNull(), id: text().primaryKey().notNull(), name: text(), email: text(), createdAt: timestamp('created_at', { withTimezone: true, mode: 'string' }), deletedAt: timestamp('deleted_at', { withTimezone: true, mode: 'string' }), }); ``` -------------------------------- ### Using useLiveQuery Hook with Expo SQLite Source: https://github.com/replit/drizzle-orm/blob/main/changelogs/drizzle-orm/0.31.1.md This hook automatically re-renders when data changes. It works with SQL-like and Drizzle queries. Ensure you have 'drizzle-orm/expo-sqlite' and 'expo-sqlite/next' installed. ```tsx import { useLiveQuery, drizzle } from 'drizzle-orm/expo-sqlite'; import { openDatabaseSync } from 'expo-sqlite/next'; import { users } from './schema'; import { Text } from 'react-native'; const expo = openDatabaseSync('db.db'); const db = drizzle(expo); const App = () => { // Re-renders automatically when data changes const { data } = useLiveQuery(db.select().from(users)); // const { data, error, updatedAt } = useLiveQuery(db.query.users.findFirst()); // const { data, error, updatedAt } = useLiveQuery(db.query.users.findMany()); return {JSON.stringify(data)}; }; export default App; ```