---
title: "Knex Kysely and Prisma Interop"
description: "The Prisma interop layer bridges Drizzle's query builder and schema definitions with Prisma Client across PostgreSQL, MySQL, and SQLite dialects. By defining Prisma extensions with $drizzle, Drizzl..."
last_updated: "2026-10-12T08:14:00.738895+00:00"
canonical_url: "https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/drivers-and-runtimes/knex-kysely-and-prisma-interop"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [drizzle-orm/src/neon-serverless/session.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/neon-serverless/session.ts)
- [drizzle-orm/src/neon-serverless/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/neon-serverless/driver.ts)
- [drizzle-orm/src/prisma/sqlite/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/sqlite/driver.ts)
- [drizzle-kit/src/api.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/api.ts)
- [drizzle-orm/src/prisma/pg/session.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/pg/session.ts)
- [drizzle-orm/src/prisma/mysql/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/mysql/driver.ts)
- [drizzle-orm/src/prisma/mysql/session.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/mysql/session.ts)
- [drizzle-orm/src/netlify-db/session.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/session.ts)
- [drizzle-orm/src/singlestore/session.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/singlestore/session.ts)
- [drizzle-orm/src/prisma/pg/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/pg/driver.ts)
- [drizzle-orm/src/netlify-db/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/driver.ts)
- [drizzle-orm/src/prisma/sqlite/session.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/sqlite/session.ts)
- [drizzle-orm/src/gel/session.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/gel/session.ts)
- [drizzle-kit/src/cli/connections.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-kit/src/cli/connections.ts)
- [drizzle-orm/src/gel/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/gel/driver.ts)
- [drizzle-orm/src/planetscale-serverless/session.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/planetscale-serverless/session.ts)
- [drizzle-orm/src/mysql2/session.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/mysql2/session.ts)
- [drizzle-orm/src/node-postgres/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/node-postgres/driver.ts)
- [drizzle-orm/src/postgres-js/session.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/postgres-js/session.ts)
- [drizzle-orm/src/singlestore/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/singlestore/driver.ts)
- [drizzle-orm/src/mysql2/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/mysql2/driver.ts)
- [drizzle-orm/src/durable-sqlite/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/durable-sqlite/driver.ts)
- [drizzle-orm/src/vercel-postgres/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/vercel-postgres/driver.ts)
- [drizzle-orm/src/vercel-postgres/session.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/vercel-postgres/session.ts)
- [drizzle-orm/src/planetscale-serverless/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/planetscale-serverless/driver.ts)
- [drizzle-orm/src/aws-data-api/pg/session.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/aws-data-api/pg/session.ts)
- [drizzle-orm/src/postgres-js/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/postgres-js/driver.ts)
- [drizzle-orm/src/pglite/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/pglite/driver.ts)
- [drizzle-orm/src/aws-data-api/pg/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/aws-data-api/pg/driver.ts)
- [drizzle-orm/src/neon-http/driver.ts](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/neon-http/driver.ts)
</details>

## Overview

The Prisma interop layer bridges Drizzle's query builder and schema definitions with Prisma Client across PostgreSQL, MySQL, and SQLite dialects. By defining Prisma extensions with `$drizzle`, Drizzle maps SQL operations to Prisma's underlying raw execution methods such as `$queryRawUnsafe`.

Sources: [drizzle-orm/src/prisma/sqlite/driver.ts:1-32](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/sqlite/driver.ts#L1-L32), [drizzle-orm/src/prisma/pg/session.ts:16-40](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/pg/session.ts#L16-L40), [drizzle-orm/src/prisma/mysql/driver.ts:1-42](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/mysql/driver.ts#L1-L42)

## Prisma PostgreSQL Driver and Session Integration

### Driver Initialization and Prisma Extension Setup

The PostgreSQL interop layer is initialized through the `drizzle()` function, which consumes a `PrismaPgConfig` configuration object excluding the schema definition. If `config.logger` is set to `true`, a `DefaultLogger` is instantiated; otherwise, custom logger instances or `false` are assigned. The function returns a Prisma extension defined via `Prisma.defineExtension`, attaching a `PrismaPgDatabase` instance to the client under the `$drizzle` property.

```typescript
export type PrismaPgConfig = Omit<DrizzleConfig, 'schema'>;

export function drizzle(config: PrismaPgConfig = {}) {
	let logger: Logger | undefined;
	if (config.logger === true) {
		logger = new DefaultLogger();
	} else if (config.logger !== false) {
		logger = config.logger;
	}

	return Prisma.defineExtension((client) => {
		return client.$extends({
			name: 'drizzle',
			client: {
				$drizzle: new PrismaPgDatabase(client, logger),
			},
		});
	});
}
```
Sources: [drizzle-orm/src/prisma/pg/driver.ts:22-40](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/pg/driver.ts#L22-L40)

`PrismaPgDatabase` extends `PgDatabase` with `PrismaPgQueryResultHKT` and an empty record type, constructing a `PgDialect` and a `PrismaPgSession` initialized with the Prisma client and session options containing the logger.

```typescript
export class PrismaPgDatabase extends PgDatabase<PrismaPgQueryResultHKT, Record<string, never>> {
	static override readonly [entityKind]: string = 'PrismaPgDatabase';

	constructor(client: PrismaClient, logger: Logger | undefined) {
		const dialect = new PgDialect();
		super(dialect, new PrismaPgSession(dialect, client, { logger }), undefined);
	}
}
```
Sources: [drizzle-orm/src/prisma/pg/driver.ts:13-20](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/pg/driver.ts#L13-L20)

### Session Management and Prepared Query Execution

`PrismaPgSession` extends `PgSession`, configuring its logger to either the provided session option or a `NoopLogger` fallback. Executing a raw SQL query delegates to `prepareQuery` using `this.dialect.sqlToQuery(query)`, subsequently calling `.execute()`.

```typescript
export class PrismaPgSession extends PgSession {
	static override readonly [entityKind]: string = 'PrismaPgSession';

	private readonly logger: Logger;

	constructor(
		dialect: PgDialect,
		private readonly prisma: PrismaClient,
		private readonly options: PrismaPgSessionOptions,
	) {
		super(dialect);
		this.logger = options.logger ?? new NoopLogger();
	}

	override execute<T>(query: SQL): Promise<T> {
		return this.prepareQuery<PreparedQueryConfig & { execute: T }>(this.dialect.sqlToQuery(query)).execute();
	}

	override prepareQuery<T extends PreparedQueryConfig = PreparedQueryConfig>(query: Query): PgPreparedQuery<T> {
		return new PrismaPgPreparedQuery(this.prisma, query, this.logger);
	}
```
Sources: [drizzle-orm/src/prisma/pg/session.ts:46-66](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/pg/session.ts#L46-L66)

> [!WARNING]
> Both `PrismaPgSession.transaction` and `PrismaPgPreparedQuery.all` throw explicit `Method not implemented.` errors when invoked, meaning transactions and array-mode responses are unsupported under the Prisma PostgreSQL interop session.

```typescript
override all(): Promise<unknown> {
	throw new Error('Method not implemented.');
}
```
Sources: [drizzle-orm/src/prisma/pg/session.ts:33-35](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/pg/session.ts#L33-L35), [drizzle-orm/src/prisma/pg/session.ts:68-73](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/pg/session.ts#L68-L73)

`PrismaPgPreparedQuery` extends `PgPreparedQuery` to execute statements against the underlying `PrismaClient`. When `execute()` is called, placeholders are filled via `fillPlaceholders()`, the query and parameters are logged, and execution proceeds through `prisma.$queryRawUnsafe()`.

```typescript
export class PrismaPgPreparedQuery<T> extends PgPreparedQuery<PreparedQueryConfig & { execute: T }> {
	static override readonly [entityKind]: string = 'PrismaPgPreparedQuery';

	constructor(
		private readonly prisma: PrismaClient,
		query: Query,
		private readonly logger: Logger,
	) {
		super(query, undefined, undefined, undefined);
	}

	override execute(placeholderValues?: Record<string, unknown>): Promise<T> {
		const params = fillPlaceholders(this.query.params, placeholderValues ?? {});
		this.logger.logQuery(this.query.sql, params);
		return this.prisma.$queryRawUnsafe(this.query.sql, ...params);
	}
```
Sources: [drizzle-orm/src/prisma/pg/session.ts:16-31](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/pg/session.ts#L16-L31)

## Prisma MySQL Session and Query Handling

### Driver Initialization and Prisma Extension Setup

The MySQL interop module exposes `PrismaMySqlDatabase`, which extends `MySqlDatabase` with `PrismaMySqlQueryResultHKT`, `PrismaMySqlPreparedQueryHKT`, and an empty record type. Its constructor instantiates a `MySqlDialect` and a `PrismaMySqlSession` equipped with the provided `PrismaClient` and logger options.

```typescript
export class PrismaMySqlDatabase
	extends MySqlDatabase<PrismaMySqlQueryResultHKT, PrismaMySqlPreparedQueryHKT, Record<string, never>>
{
	static override readonly [entityKind]: string = 'PrismaMySqlDatabase';

	constructor(client: PrismaClient, logger: Logger | undefined) {
		const dialect = new MySqlDialect();
		super(dialect, new PrismaMySqlSession(dialect, client, { logger }), undefined, 'default');
	}
}
```
Sources: [drizzle-orm/src/prisma/mysql/driver.ts:13-22](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/mysql/driver.ts#L13-L22)

The `drizzle()` entry point accepts a `PrismaMySqlConfig` type, omitting the `schema` property from `DrizzleConfig`. If `config.logger` is set to `true`, a `DefaultLogger` is created; otherwise, custom loggers or `false` are preserved. The function returns a Prisma extension via `Prisma.defineExtension`, appending the `$drizzle` database client instance to the extended Prisma client.

```typescript
export type PrismaMySqlConfig = Omit<DrizzleConfig, 'schema'>;

export function drizzle(config: PrismaMySqlConfig = {}) {
	let logger: Logger | undefined;
	if (config.logger === true) {
		logger = new DefaultLogger();
	} else if (config.logger !== false) {
		logger = config.logger;
	}

	return Prisma.defineExtension((client) => {
		return client.$extends({
			name: 'drizzle',
			client: {
				$drizzle: new PrismaMySqlDatabase(client, logger),
			},
		});
	});
}
```
Sources: [drizzle-orm/src/prisma/mysql/driver.ts:24-42](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/mysql/driver.ts#L24-L42)

### Session Management and Prepared Query Execution

`PrismaMySqlSession` extends `MySqlSession`, resolving its logger option to either the supplied logger or a `NoopLogger` fallback. The session implements raw execution by converting `SQL` objects via `this.dialect.sqlToQuery(query)` and delegating to `prepareQuery().execute()`.

```typescript
export class PrismaMySqlSession extends MySqlSession {
	static override readonly [entityKind]: string = 'PrismaMySqlSession';

	private readonly logger: Logger;

	constructor(
		dialect: MySqlDialect,
		private readonly prisma: PrismaClient,
		private readonly options: PrismaMySqlSessionOptions,
	) {
		super(dialect);
		this.logger = options.logger ?? new NoopLogger();
	}

	override execute<T>(query: SQL): Promise<T> {
		return this.prepareQuery<MySqlPreparedQueryConfig & { execute: T }>(this.dialect.sqlToQuery(query)).execute();
	}

```
Sources: [drizzle-orm/src/prisma/mysql/session.ts:43-60](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/mysql/session.ts#L43-L60)

```typescript
override prepareQuery<T extends MySqlPreparedQueryConfig = MySqlPreparedQueryConfig>(
	query: Query,
): MySqlPreparedQuery<T> {
	return new PrismaMySqlPreparedQuery(this.prisma, query, this.logger);
}
```
Sources: [drizzle-orm/src/prisma/mysql/session.ts:65-69](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/mysql/session.ts#L65-L69)

> [!WARNING]
> `PrismaMySqlSession` does not implement `all`, `transaction`, or `PrismaMySqlPreparedQuery.iterator`. Invoking any of these methods throws an explicit `Method not implemented.` error at runtime.

```typescript
override iterator(_placeholderValues?: Record<string, unknown> | undefined): AsyncGenerator<unknown, any, unknown> {
	throw new Error('Method not implemented.');
}
```
Sources: [drizzle-orm/src/prisma/mysql/session.ts:19-21](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/mysql/session.ts#L19-L21), [drizzle-orm/src/prisma/mysql/session.ts:61-63](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/mysql/session.ts#L61-L63), [drizzle-orm/src/prisma/mysql/session.ts:71-84](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/mysql/session.ts#L71-L84)

`PrismaMySqlPreparedQuery` extends `MySqlPreparedQuery` to bind queries against `PrismaClient`. When `execute()` is called, parameter placeholders are populated using `fillPlaceholders()`, the query is logged, and the statement executes through `prisma.$queryRawUnsafe()`.

```typescript
export class PrismaMySqlPreparedQuery<T> extends MySqlPreparedQuery<MySqlPreparedQueryConfig & { execute: T }> {
	override iterator(_placeholderValues?: Record<string, unknown> | undefined): AsyncGenerator<unknown, any, unknown> {
		throw new Error('Method not implemented.');
	}
	static override readonly [entityKind]: string = 'PrismaMySqlPreparedQuery';

	constructor(
		private readonly prisma: PrismaClient,
		private readonly query: Query,
		private readonly logger: Logger,
	) {
		super(undefined, undefined, undefined);
	}

	override execute(placeholderValues?: Record<string, unknown>): Promise<T> {
		const params = fillPlaceholders(this.query.params, placeholderValues ?? {});
		this.logger.logQuery(this.query.sql, params);
		return this.prisma.$queryRawUnsafe(this.query.sql, ...params);
	}
}
```
Sources: [drizzle-orm/src/prisma/mysql/session.ts:18-37](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/mysql/session.ts#L18-L37)

## Prisma SQLite Async Driver Architecture

### Driver Initialization and Prisma Extension Setup

The SQLite interop module provides a `drizzle()` function that accepts a `PrismaSQLiteConfig` type, omitting the `schema` property from `DrizzleConfig`. It instantiates a `SQLiteAsyncDialect` and resolves the logger configuration: setting up a `DefaultLogger` when `config.logger` is `true`, preserving custom loggers, or omitting it otherwise.

```typescript
export type PrismaSQLiteConfig = Omit<DrizzleConfig, 'schema'>;

export function drizzle(config: PrismaSQLiteConfig = {}) {
	const dialect = new SQLiteAsyncDialect();
	let logger: Logger | undefined;
	if (config.logger === true) {
		logger = new DefaultLogger();
	} else if (config.logger !== false) {
		logger = config.logger;
	}
```
Sources: [drizzle-orm/src/prisma/sqlite/driver.ts:11-20](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/sqlite/driver.ts#L11-L20)

The function returns a Prisma extension via `Prisma.defineExtension()`, instantiating a `PrismaSQLiteSession` with the underlying client, dialect, and logger. It then injects the `$drizzle` database client initialized as a `BaseSQLiteDatabase` with an `'async'` mode into the extended client.

```typescript
return Prisma.defineExtension((client) => {
	const session = new PrismaSQLiteSession(client, dialect, { logger });

	return client.$extends({
		name: 'drizzle',
		client: {
			$drizzle: new BaseSQLiteDatabase('async', dialect, session, undefined) as PrismaSQLiteDatabase,
		},
	});
});
```
Sources: [drizzle-orm/src/prisma/sqlite/driver.ts:22-31](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/sqlite/driver.ts#L22-L31)

### Session Management and Prepared Query Execution

`PrismaSQLiteSession` extends `SQLiteSession` with `'async'` execution mode, configuring its logger to either the provided options logger or a `NoopLogger` fallback. The session implements `prepareQuery()` to construct `PrismaSQLitePreparedQuery` instances and overrides `transaction()` to throw an unimplemented error.

```typescript
export class PrismaSQLiteSession extends SQLiteSession<'async', unknown, Record<string, never>, Record<string, never>> {
	static override readonly [entityKind]: string = 'PrismaSQLiteSession';

	private readonly logger: Logger;

	constructor(
		private readonly prisma: PrismaClient,
		dialect: SQLiteAsyncDialect,
		options: PrismaSQLiteSessionOptions,
	) {
		super(dialect);
		this.logger = options.logger ?? new NoopLogger();
	}

	override prepareQuery<T extends Omit<PreparedQueryConfig, 'run'>>(
		query: Query,
		fields: SelectedFieldsOrdered | undefined,
		executeMethod: SQLiteExecuteMethod,
	): PrismaSQLitePreparedQuery<T> {
		return new PrismaSQLitePreparedQuery(this.prisma, query, this.logger, executeMethod);
	}

	override transaction<T>(
		_transaction: (tx: SQLiteTransaction<'async', unknown, Record<string, never>, Record<string, never>>) => Promise<T>,
		_config?: SQLiteTransactionConfig,
	): Promise<T> {
		throw new Error('Method not implemented.');
	}
}
```
Sources: [drizzle-orm/src/prisma/sqlite/session.ts:62-90](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/sqlite/session.ts#L62-L90)

> [!WARNING]
> `PrismaSQLiteSession.transaction()` and `PrismaSQLitePreparedQuery.values()` are not implemented. Invoking either method throws a `Method not implemented.` error at runtime.

```typescript
override values(_placeholderValues?: Record<string, unknown> | undefined): Promise<never> {
	throw new Error('Method not implemented.');
}
```
Sources: [drizzle-orm/src/prisma/sqlite/session.ts:49-51](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/sqlite/session.ts#L49-L51), [drizzle-orm/src/prisma/sqlite/session.ts:84-89](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/sqlite/session.ts#L84-L89)

`PrismaSQLitePreparedQuery` extends `SQLitePreparedQuery` to execute statements against `PrismaClient`. The `all()` method populates statement parameters via `fillPlaceholders()`, logs the query, and delegates to `prisma.$queryRawUnsafe()`.

```typescript
export class PrismaSQLitePreparedQuery<T extends PreparedQueryConfig = PreparedQueryConfig> extends SQLitePreparedQuery<
	{ type: 'async'; run: []; all: T['all']; get: T['get']; values: never; execute: T['execute'] }
> {
	static override readonly [entityKind]: string = 'PrismaSQLitePreparedQuery';

	constructor(
		private readonly prisma: PrismaClient,
		query: Query,
		private readonly logger: Logger,
		executeMethod: SQLiteExecuteMethod,
	) {
		super('async', executeMethod, query);
	}

	override all(placeholderValues?: Record<string, unknown>): Promise<T['all']> {
		const params = fillPlaceholders(this.query.params, placeholderValues ?? {});
		this.logger.logQuery(this.query.sql, params);
		return this.prisma.$queryRawUnsafe(this.query.sql, ...params);
	}
```
Sources: [drizzle-orm/src/prisma/sqlite/session.ts:19-37](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/sqlite/session.ts#L19-L37)

The prepared query handles additional execution modalities by building upon `all()`. Specifically, `run()` executes the query and returns an empty array, `get()` retrieves the first row from the result set, and `isResponseInArrayMode()` explicitly returns `false`.

```typescript
	override async run(placeholderValues?: Record<string, unknown> | undefined): Promise<[]> {
		await this.all(placeholderValues);
		return [];
	}

	override async get(placeholderValues?: Record<string, unknown> | undefined): Promise<T['get']> {
		const all = await this.all(placeholderValues) as unknown[];
		return all[0];
	}

	override values(_placeholderValues?: Record<string, unknown> | undefined): Promise<never> {
		throw new Error('Method not implemented.');
	}

	override isResponseInArrayMode(): boolean {
		return false;
	}
}
```
Sources: [drizzle-orm/src/prisma/sqlite/session.ts:39-56](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/prisma/sqlite/session.ts#L39-L56)

## Serverless and Managed Adapter Interoperability

### Neon and Netlify DB Driver Initialization

The serverless architecture adapts HTTP and WebSocket-based PostgreSQL clients for connectionless or pooled execution runtimes. The Neon serverless driver exports the `NeonDriver` and `NeonDatabase` classes, supporting initialization via connection strings, pool configurations, or pre-constructed client instances through `drizzle()`.

```typescript
export function drizzle<
	TSchema extends Record<string, unknown> = Record<string, never>,
	TClient extends NeonClient = Pool,
>(
	...params: [
		TClient | string,
	] | [
		TClient | string,
		DrizzleConfig<TSchema>,
	] | [
		(
			& DrizzleConfig<TSchema>
			& ({
				connection: string | PoolConfig;
			} | {
				client: TClient;
			})
			& {
				ws?: any;
			}
		),
	]
): NeonDatabase<TSchema> & {
	$client: NeonClient extends TClient ? Pool : TClient;
} {
```
Sources: [drizzle-orm/src/neon-serverless/driver.ts:91-115](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/neon-serverless/driver.ts#L115-L147)

Similarly, the Netlify DB driver establishes type parsers during driver construction for temporal and array data types using `types.setTypeParser()`.

```typescript
export class NetlifyDbDriver {
	static readonly [entityKind]: string = 'NetlifyDbDriver';

	constructor(
		private httpClient: NeonHttpClient,
		private pool: Pool,
		private dialect: PgDialect,
		private options: NetlifyDbDriverOptions = {},
	) {
		this.initMappers();
	}

	createSession(
		schema: V1.RelationalSchemaConfig<V1.TablesRelationalConfig> | undefined,
	): NetlifyDbSession<Record<string, unknown>, V1.TablesRelationalConfig> {
		return new NetlifyDbSession(this.httpClient, this.pool, this.dialect, schema, {
			logger: this.options.logger,
			cache: this.options.cache,
		});
	}

	initMappers() {
		types.setTypeParser(types.builtins.TIMESTAMPTZ, (val: any) => val);
		types.setTypeParser(types.builtins.TIMESTAMP, (val: any) => val);
		types.setTypeParser(types.builtins.DATE, (val: any) => val);
		types.setTypeParser(types.builtins.INTERVAL, (val: any) => val);
		types.setTypeParser(1231, (val: any) => val);
		types.setTypeParser(1115, (val: any) => val);
		types.setTypeParser(1185, (val: any) => val);
		types.setTypeParser(1187, (val: any) => val);
		types.setTypeParser(1182, (val: any) => val);
	}
}
```
Sources: [drizzle-orm/src/netlify-db/driver.ts:37-69](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/driver.ts#L37-L69)

Type parsers registered during Netlify DB driver initialization map specific PostgreSQL built-in type OIDs directly to raw values without altering formats.

| OID Constant / Built-in | Parser Target | Sources |
| :--- | :--- | :--- |
| `types.builtins.TIMESTAMPTZ` | Returns raw value | [drizzle-orm/src/netlify-db/driver.ts:59](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/driver.ts#L59) |
| `types.builtins.TIMESTAMP` | Returns raw value | [drizzle-orm/src/netlify-db/driver.ts:60](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/driver.ts#L60) |
| `types.builtins.DATE` | Returns raw value | [drizzle-orm/src/netlify-db/driver.ts:61](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/driver.ts#L61) |
| `types.builtins.INTERVAL` | Returns raw value | [drizzle-orm/src/netlify-db/driver.ts:62](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/driver.ts#L62) |
| `1231` | Returns raw value | [drizzle-orm/src/netlify-db/driver.ts:63](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/driver.ts#L63) |
| `1115` | Returns raw value | [drizzle-orm/src/netlify-db/driver.ts:64](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/driver.ts#L64) |
| `1185` | Returns raw value | [drizzle-orm/src/netlify-db/driver.ts:65](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/driver.ts#L65) |
| `1187` | Returns raw value | [drizzle-orm/src/netlify-db/driver.ts:66](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/driver.ts#L66) |
| `1182` | Returns raw value | [drizzle-orm/src/netlify-db/driver.ts:67](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/driver.ts#L67) |

Sources: [drizzle-orm/src/netlify-db/driver.ts:59-67](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/driver.ts#L59-L67)

### Session Execution and Transaction Semantics

`NeonSession` manages query preparation, logging, caching, and statement execution. When handling transactions, it inspects whether the underlying client is a `Pool` instance; if so, it acquires a dedicated client connection for the duration of the transaction block and releases it afterward in a `finally` block.

```typescript
override async transaction<T>(
	transaction: (tx: NeonTransaction<TFullSchema, TSchema>) => Promise<T>,
	config: PgTransactionConfig = {},
): Promise<T> {
	const session = this.client instanceof Pool // eslint-disable-line no-instanceof/no-instanceof
		? new NeonSession(await this.client.connect(), this.dialect, this.schema, this.options)
		: this;
	const tx = new NeonTransaction<TFullSchema, TSchema>(this.dialect, session, this.schema);
	await tx.execute(sql`begin ${tx.getTransactionConfigSQL(config)}`);
	try {
		const result = await transaction(tx);
		await tx.execute(sql`commit`);
		return result;
	} catch (error) {
		await tx.execute(sql`rollback`);
		throw error;
	} finally {
		if (this.client instanceof Pool) { // eslint-disable-line no-instanceof/no-instanceof
			(session.client as PoolClient).release();
		}
	}
}
```
Sources: [drizzle-orm/src/neon-serverless/session.ts:260-281](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/neon-serverless/session.ts#L260-L281)

> [!WARNING]
> `NeonSession.transaction()` checks `this.client instanceof Pool` to branch between acquiring a pooled client connection or reusing the existing session client. Failing to release pool clients in custom implementations leaks connections.

```typescript
const session = this.client instanceof Pool // eslint-disable-line no-instanceof/no-instanceof
	? new NeonSession(await this.client.connect(), this.dialect, this.schema, this.options)
	: this;
```
Sources: [drizzle-orm/src/neon-serverless/session.ts:264-266](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/neon-serverless/session.ts#L264-L266), [drizzle-orm/src/neon-serverless/session.ts:277-279](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/neon-serverless/session.ts#L277-L279)

Nested transactions in both `NeonTransaction` and `NetlifyDbTransaction` utilize PostgreSQL savepoints with automatically incremented identifiers. Each nested transaction level generates a savepoint named via `sp${this.nestedIndex + 1}`, releasing or rolling back to that savepoint depending on execution success.

```typescript
override async transaction<T>(transaction: (tx: NeonTransaction<TFullSchema, TSchema>) => Promise<T>): Promise<T> {
	const savepointName = `sp${this.nestedIndex + 1}`;
	const tx = new NeonTransaction<TFullSchema, TSchema>(this.dialect, this.session, this.schema, this.nestedIndex + 1);
	await tx.execute(sql.raw(`savepoint ${savepointName}`));
	try {
		const result = await transaction(tx);
		await tx.execute(sql.raw(`release savepoint ${savepointName}`));
		return result;
	} catch (e) {
		await tx.execute(sql.raw(`rollback to savepoint ${savepointName}`));
		throw e;
	}
}
```
Sources: [drizzle-orm/src/neon-serverless/session.ts:290-302](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/neon-serverless/session.ts#L290-L302), [drizzle-orm/src/netlify-db/session.ts:273-292](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/netlify-db/session.ts#L273-L292)

## Cloud Runtime Driver Interop Patterns

### Gel Driver and Client Initialization

The Gel driver interface supports initialization via connection strings, existing `Client` instances, or configuration objects containing connection options. The `drizzle()` factory function inspects its parameters to construct a `GelDriver` instance paired with a `GelDialect`.

| Parameter Variant | Handling Behavior | Sources |
| :--- | :--- | :--- |
| `string` (DSN) | Creates a client via `createClient({ dsn })` | [drizzle-orm/src/gel/driver.ts:109-113](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/gel/driver.ts#L109-L113) |
| `Object` (Config with `client`) | Uses the provided client instance directly | [drizzle-orm/src/gel/driver.ts:115-121](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/gel/driver.ts#L115-L121) |
| `Object` (Config with `connection`) | Instantiates a client with `connection` options | [drizzle-orm/src/gel/driver.ts:115-126](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/gel/driver.ts#L115-L126) |
| Direct `Client` | Constructs database instance using the client | [drizzle-orm/src/gel/driver.ts:128](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/gel/driver.ts#L128) |
| `drizzle.mock()` | Initializes a mock client object | [drizzle-orm/src/gel/driver.ts:131-138](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/gel/driver.ts#L131-L138) |

Sources: [drizzle-orm/src/gel/driver.ts:109-138](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/gel/driver.ts#L109-L138)

```typescript
export function drizzle<
	TSchema extends Record<string, unknown> = Record<string, never>,
	TClient extends GelClient = Client,
>(
	...params:
		| [TClient | string]
		| [TClient | string, DrizzleConfig<TSchema>]
		| [
			& DrizzleConfig<TSchema>
			& (
				| {
					connection: string | ConnectOptions;
				}
				| {
					client: TClient;
				}
			),
		]
```
Sources: [drizzle-orm/src/gel/driver.ts:88-105](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/gel/driver.ts#L88-L105)

### AWS Data API Parameter Customization

The AWS Data API PostgreSQL driver specializes query execution through `AwsPgDialect`, which overrides parameter escaping and array handling. Positional parameters are formatted as `:${num + 1}`, and array columns in insert and update operations are explicitly cast to their SQL type definitions.

```typescript
export class AwsPgDialect extends PgDialect {
	static override readonly [entityKind]: string = 'AwsPgDialect';

	override escapeParam(num: number): string {
		return `:${num + 1}`;
	}

```
Sources: [drizzle-orm/src/aws-data-api/pg/driver.ts:50-56](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/aws-data-api/pg/driver.ts#L50-L56), [drizzle-orm/src/aws-data-api/pg/driver.ts:67-72](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/aws-data-api/pg/driver.ts#L67-L72)

> [!NOTE]
> `AwsPgDialect` intercepts insert and update building to locate encoder instances matching `PgArray`. When array values are present, it wraps them in an explicit `cast(... as ...)` expression to satisfy strict AWS RDS Data API typing requirements.

```typescript
	const colValue = value[fieldName];
	if (
		is(colValue, Param) && colValue.value !== undefined && is(colValue.encoder, PgArray)
		&& Array.isArray(colValue.value)
	) {
		value[fieldName] = sql`cast(${colValue} as ${sql.raw(colValue.encoder.getSQLType())})`;
	}
}
```
Sources: [drizzle-orm/src/aws-data-api/pg/driver.ts:65-72](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/aws-data-api/pg/driver.ts#L65-L72), [drizzle-orm/src/aws-data-api/pg/driver.ts:83-90](https://github.com/blade47/drizzle-orm/blob/48e5406027103a9fca6eb66417187c4a8b5c6aa3/drizzle-orm/src/aws-data-api/pg/driver.ts#L83-L90)

## Related

- [Sessions and Transactions](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/technical/core-architecture/sessions-and-transactions)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/e1b68fed-3c4e-4c95-b2ba-ebf050f78025/llms.txt) for all pages in this wiki.
