0.39.0

drizzle-team/drizzle-orm0.39.0Jan 27, 2025by github-actions[bot]

AI Summary

Drizzle ORM 0.39.0 introduces Bun SQL driver support for Bun v1.2.0, extends WITH clause functionality to support INSERT, UPDATE, DELETE and raw SQL templates, adds Neon Identity schema with users_sync table, and includes a new getViewName utility function.

Key Highlights

  • Added new Bun SQL driver support for Bun v1.2.0 with some limitations (json/jsonb, datetime types, and array types)
  • WITH clause now supports INSERT, UPDATE, DELETE and raw SQL templates in CTEs
  • Added neon_identity schema and users_sync table for Neon Identity integration
  • New getViewName utility function for retrieving view names
  • Fixed $count API errors with replicas and vercel-postgres
  • Fixed type coercion issues in drizzle-zod

New Features

  • Bun SQL driver support (drizzle-orm/bun-sql)
  • WITH clause support for INSERT, UPDATE, DELETE and raw SQL templates in CTEs
  • Neon Identity schema (neon_identity) with users_sync table
  • getViewName utility function for views
  • Type coercion improvements in drizzle-zod
  • Fixed $count API with replicas and vercel-postgres

Full Release Notes

# New features

## Bun SQL driver support
You can now use the new Bun SQL driver released in Bun v1.2.0 with Drizzle

> In version 1.2.0, Bun has issues with executing concurrent statements, which may lead to errors if you try to run several queries simultaneously.
We've created a [github issue](https://github.com/oven-sh/bun/issues/16774) that you can track. Once it's fixed, you should no longer encounter any such errors on Bun's SQL side

```ts
import { drizzle } from 'drizzle-orm/bun-sql';

const db = drizzle(process.env.PG_DB_URL!);

const result = await db.select().from(...);
```

or you can use Bun SQL instance

```ts
import { drizzle } from 'drizzle-orm/bun-sql';
import { SQL } from 'bun';

const client = new SQL(process.env.PG_DB_URL!);
const db = drizzle({ client });

const result = await db.select().from(...);
```

Current Limitations:

- `json` and `jsonb` inserts and selects currently perform an additional `JSON.stringify` on the Bun SQL side. Once this is removed, they should work properly. You can always use custom types and redefine the mappers to and from the database.
- `datetime`, `date`, and `timestamp` will not work properly when using `mode: string` in Drizzle. This is due to Bun's API limitations, which prevent custom parsers for queries. As a result, Drizzle cannot control the response sent from Bun SQL to Drizzle. Once this feature is added to Bun SQL, it should work as expected.
- `array` types currently have issues in Bun SQL.

> You can check more in [Bun docs](https://bun.sh/docs/api/sql)
>
> You can check more getting started examples in [Drizzle docs](https://orm.drizzle.team/docs/get-started/bun-sql-new)

## WITH now supports INSERT, UPDATE, DELETE and raw sql template

**`with` and `insert`**

```ts
const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: text('name').notNull(),
});

const sq = db.$with('sq').as(
    db.insert(users).values({ name: 'John' }).returning(),
);

const result = await db.with(sq).select().from(sq);
```

**`with` and `update`**

```ts
const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: text('name').notNull(),
});

const sq = db.$with('sq').as(
    db.update(users).set({ age: 25 }).where(eq(users.name, 'John')).returning(),
);
const result = await db.with(sq).select().from(sq);
```

**`with` and `delete`**

```ts
const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: text('name').notNull(),
});

const sq = db.$with('sq').as(
  db.delete(users).where(eq(users.name, 'John')).returning(),
);

const result = await db.with(sq).select().from(sq);
```

**`with` and `sql`**

```ts
const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: text('name').notNull(),
});

const sq = db.$with('sq', {
  userId: users.id,
  data: {
    name: users.name,
  },
}).as(sql`select * from ${users} where ${users.name} = 'John'`);

const result = await db.with(sq).select().from(sq);
```

## New tables in `/neon` import

In this release you can use `neon_identity` schema and `users_sync` table inside this schema by just importing it from `/neon`

```ts
// "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' }),
});
```

# Utils and small improvements

## `getViewName` util function

```ts
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)
```

# Bug fixed and GitHub issue closed

- [[FEATURE]: allow INSERT in CTEs (WITH clauses)](https://github.com/drizzle-team/drizzle-orm/issues/2078)
- [[FEATURE]: Support Raw SQL in CTE Query Builder](https://github.com/drizzle-team/drizzle-orm/issues/2168)
- [[FEATURE]: include pre-defined database objects related to Neon Identity in drizzle-orm](https://github.com/drizzle-team/drizzle-orm/issues/3959)
- [[BUG]: $count is undefined on withReplicas](https://github.com/drizzle-team/drizzle-orm/issues/3951)
- [[FEATURE]: get[Materialized]ViewName, ie getTableName but for (materialized) views.](https://github.com/drizzle-team/drizzle-orm/issues/3946)
- [[BUG]: $count API error with vercel-postgres](https://github.com/drizzle-team/drizzle-orm/issues/3710)
- [[BUG]: Cannot use schema.coerce on refining drizzle-zod types](https://github.com/drizzle-team/drizzle-orm/issues/3842)
- [[FEATURE]: Type Coercion in drizzle-zod](https://github.com/drizzle-team/drizzle-orm/issues/776)
- [[BUG]: The inferred type of X cannot be named without a reference to ../../../../../node_modules/drizzle-zod/schema.types.internal.mjs](https://github.com/drizzle-team/drizzle-orm/issues/3732)
- [[BUG]: drizzle-zod excessively deep and possibly infinite types](https://github.com/drizzle-team/drizzle-orm/issues/3869)