Headless TypeScript ORM with a head. Runs on Node, Bun and Deno. Lives on the Edge and yes, it's a JavaScript ORM too 😅
.if()
function added to all WHERE expressionsasync function someFunction(categories: string[] = [], views = 0) {
await db
.select()
.from(users)
.where(
and(
gt(posts.views, views).if(views > 100),
inArray(posts.category, categories).if(categories.length > 0),
),
);
}
.all
, .values
, .execute
functions in AWS DataAPIsetWhere
and targetWhere
fields to .onConflictDoUpdate()
config in SQLite instead of single where
fielddb._.fullSchema
:warning: Only available in
drizzle-orm
for now,drizzle-kit
support will arrive soon
import { pgSchema } from 'drizzle-orm/pg-core';
const mySchema = pgSchema('mySchema');
const colors = mySchema.enum('colors', ['red', 'green', 'blue']);
migrate()
function to use batch API (#2137)where
clause in Postgres .onConflictDoUpdate
method into setWhere
and targetWhere
clauses, to support both where
cases in on conflict ...
clause (fixes #1628, #1302 via #2056)where
clause in Postgres .onConflictDoNothing
method, as it was placed in a wrong spot (fixes #1628 via #2056)Thanks @hugo082 and @livingforjesus!
PGlite is a WASM Postgres build packaged into a TypeScript client library that enables you to run Postgres in the browser, Node.js and Bun, with no need to install any other dependencies. It is only 2.6mb gzipped.
It can be used as an ephemeral in-memory database, or with persistence either to the file system (Node/Bun) or indexedDB (Browser).
Unlike previous "Postgres in the browser" projects, PGlite does not use a Linux virtual machine - it is simply Postgres in WASM.
Usage Example
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);
There are currently 2 limitations, that should be fixed on Pglite side:
$onUpdate
functionality for PostgreSQL, MySQL and SQLiteAdds a dynamic update value to the column.
The function will be called when the row is updated, and the returned value will be used as the column value if none is provided.
If no default
(or $defaultFn
) value is provided, the function will be called when the row is inserted as well, and the returned value will be used as the column value.
Note: This value does not affect the
drizzle-kit
behavior, it is only used at runtime indrizzle-orm
.
const usersOnUpdate = pgTable('users_on_update', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
updateCounter: integer('update_counter').default(sql`1`).$onUpdateFn(() => sql`update_counter + 1`),
updatedAt: timestamp('updated_at', { mode: 'date', precision: 3 }).$onUpdate(() => new Date()),
alwaysNull: text('always_null').$type<string | null>().$onUpdate(() => null),
});
Thanks @Angelelz and @gabrielDonnantuoni!
According their official website, Xata is a Postgres data platform with a focus on reliability, scalability, and developer experience. The Xata Postgres service is currently in beta, please see the Xata docs on how to enable it in your account.
Drizzle ORM natively supports both the xata
driver with drizzle-orm/xata
package and the postgres
or pg
drivers for accessing a Xata Postgres database.
The following example use the Xata generated client, which you obtain by running the xata init CLI command.
pnpm add drizzle-orm @xata.io/client
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(...);
You can also connect to Xata using pg
or postgres.js
drivers
db.execute(...)
) to batch API in Neon HTTP driver@neondatabase/serverless
HTTP driver types issue (#1945, neondatabase/serverless#66).run()
result (https://github.com/drizzle-team/drizzle-orm/pull/2038)LibSQL migrations have been updated to utilize batch execution instead of transactions. As stated in the documentation, LibSQL now supports batch operations
A batch consists of multiple SQL statements executed sequentially within an implicit transaction. The backend handles the transaction: success commits all changes, while any failure results in a full rollback with no modifications.
Usage Example
import { open } from '@op-engineering/op-sqlite';
import { drizzle } from 'drizzle-orm/op-sqlite';
const opsqlite = open({
name: 'myDB',
});
const db = drizzle(opsqlite);
await db.select().from(users);
For more usage and setup details, please check our op-sqlite docs