|
| 1 | +# New features |
| 2 | + |
| 3 | +## Bun SQL driver support |
| 4 | +You can now use the new Bun SQL driver released in Bun v1.2.0 with Drizzle |
| 5 | + |
| 6 | +```ts |
| 7 | +import { drizzle } from 'drizzle-orm/bun-sql'; |
| 8 | + |
| 9 | +const db = drizzle(process.env.PG_DB_URL!); |
| 10 | + |
| 11 | +const result = await db.select().from(...); |
| 12 | +``` |
| 13 | + |
| 14 | +or you can use Bun SQL instance |
| 15 | + |
| 16 | +```ts |
| 17 | +import { drizzle } from 'drizzle-orm/bun-sqlite'; |
| 18 | +import { SQL } from 'bun'; |
| 19 | + |
| 20 | +const client = new SQL(process.env.PG_DB_URL!); |
| 21 | +const db = drizzle({ client }); |
| 22 | + |
| 23 | +const result = await db.select().from(...); |
| 24 | +``` |
| 25 | + |
| 26 | +Current Limitations: |
| 27 | + |
| 28 | +- `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. |
| 29 | +- `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. |
| 30 | +- `array` types currently have issues in Bun SQL. |
| 31 | + |
| 32 | +> You can check more in [Bun docs](https://bun.sh/docs/api/sql) |
| 33 | +> |
| 34 | +> You can check more getting started examples in [Drizzle docs](https://orm.drizzle.team/docs/get-started/bun-sql-new) |
| 35 | +
|
| 36 | +## WITH now supports INSERT, UPDATE, DELETE and raw sql template |
| 37 | + |
| 38 | +**`with` and `insert`** |
| 39 | + |
| 40 | +```ts |
| 41 | +const users = pgTable('users', { |
| 42 | + id: serial('id').primaryKey(), |
| 43 | + name: text('name').notNull(), |
| 44 | +}); |
| 45 | + |
| 46 | +const sq = db.$with('sq').as( |
| 47 | + db.insert(users).values({ name: 'John' }).returning(), |
| 48 | +); |
| 49 | + |
| 50 | +const result = await db.with(sq).select().from(sq); |
| 51 | +``` |
| 52 | + |
| 53 | +**`with` and `update`** |
| 54 | + |
| 55 | +```ts |
| 56 | +const users = pgTable('users', { |
| 57 | + id: serial('id').primaryKey(), |
| 58 | + name: text('name').notNull(), |
| 59 | +}); |
| 60 | + |
| 61 | +const sq = db.$with('sq').as( |
| 62 | + db.update(users).set({ age: 25 }).where(eq(users.name, 'John')).returning(), |
| 63 | +); |
| 64 | +const result = await db.with(sq).select().from(sq); |
| 65 | +``` |
| 66 | + |
| 67 | +**`with` and `delete`** |
| 68 | + |
| 69 | +```ts |
| 70 | +const users = pgTable('users', { |
| 71 | + id: serial('id').primaryKey(), |
| 72 | + name: text('name').notNull(), |
| 73 | +}); |
| 74 | + |
| 75 | +const sq = db.$with('sq').as( |
| 76 | + db.delete(users).where(eq(users.name, 'John')).returning(), |
| 77 | +); |
| 78 | + |
| 79 | +const result = await db.with(sq).select().from(sq); |
| 80 | +``` |
| 81 | + |
| 82 | +**`with` and `sql`** |
| 83 | + |
| 84 | +```ts |
| 85 | +const users = pgTable('users', { |
| 86 | + id: serial('id').primaryKey(), |
| 87 | + name: text('name').notNull(), |
| 88 | +}); |
| 89 | + |
| 90 | +const sq = db.$with('sq', { |
| 91 | + userId: users.id, |
| 92 | + data: { |
| 93 | + name: users.name, |
| 94 | + }, |
| 95 | +}).as(sql`select * from ${users} where ${users.name} = 'John'`); |
| 96 | + |
| 97 | +const result = await db.with(sq).select().from(sq); |
| 98 | +``` |
| 99 | + |
| 100 | +## New tables in `/neon` import |
| 101 | + |
| 102 | +In this release you can use `neon_identity` schema and `users_sync` table inside this schema by just importing it from `/neon` |
| 103 | + |
| 104 | +```ts |
| 105 | +// "drizzle-orm/neon" |
| 106 | +const neonIdentitySchema = pgSchema('neon_identity'); |
| 107 | + |
| 108 | +/** |
| 109 | + * Table schema of the `users_sync` table used by Neon Identity. |
| 110 | + * This table automatically synchronizes and stores user data from external authentication providers. |
| 111 | + * |
| 112 | + * @schema neon_identity |
| 113 | + * @table users_sync |
| 114 | + */ |
| 115 | +export const usersSync = neonIdentitySchema.table('users_sync', { |
| 116 | + rawJson: jsonb('raw_json').notNull(), |
| 117 | + id: text().primaryKey().notNull(), |
| 118 | + name: text(), |
| 119 | + email: text(), |
| 120 | + createdAt: timestamp('created_at', { withTimezone: true, mode: 'string' }), |
| 121 | + deletedAt: timestamp('deleted_at', { withTimezone: true, mode: 'string' }), |
| 122 | +}); |
| 123 | +``` |
| 124 | + |
| 125 | +# Utils and small improvements |
| 126 | + |
| 127 | +## `getViewName` util function |
| 128 | + |
| 129 | +```ts |
| 130 | +import { getViewName } from 'drizzle-orm/sql' |
| 131 | + |
| 132 | +export const user = pgTable("user", { |
| 133 | + id: serial(), |
| 134 | + name: text(), |
| 135 | + email: text(), |
| 136 | +}); |
| 137 | + |
| 138 | +export const userView = pgView("user_view").as((qb) => qb.select().from(user)); |
| 139 | + |
| 140 | +const viewName = getViewName(userView) |
| 141 | +``` |
| 142 | + |
| 143 | +# Bug fixed and GitHub issue closed |
| 144 | + |
| 145 | +- [[FEATURE]: allow INSERT in CTEs (WITH clauses)](https://github.com/drizzle-team/drizzle-orm/issues/2078) |
| 146 | +- [[FEATURE]: Support Raw SQL in CTE Query Builder](https://github.com/drizzle-team/drizzle-orm/issues/2168) |
| 147 | +- [[FEATURE]: include pre-defined database objects related to Neon Identity in drizzle-orm](https://github.com/drizzle-team/drizzle-orm/issues/3959) |
| 148 | +- [[BUG]: $count is undefined on withReplicas](https://github.com/drizzle-team/drizzle-orm/issues/3951) |
| 149 | +- [[FEATURE]: get[Materialized]ViewName, ie getTableName but for (materialized) views.](https://github.com/drizzle-team/drizzle-orm/issues/3946) |
| 150 | +- [[BUG]: $count API error with vercel-postgres](https://github.com/drizzle-team/drizzle-orm/issues/3710) |
| 151 | +- [[BUG]: Cannot use schema.coerce on refining drizzle-zod types](https://github.com/drizzle-team/drizzle-orm/issues/3842) |
| 152 | +- [[FEATURE]: Type Coercion in drizzle-zod](https://github.com/drizzle-team/drizzle-orm/issues/776) |
| 153 | +- [[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) |
| 154 | +- [[BUG]: drizzle-zod excessively deep and possibly infinite types](https://github.com/drizzle-team/drizzle-orm/issues/3869) |
0 commit comments