Skip to content

drizzle-orm

0.45.4
drizzle-team/drizzle-orm

ORM

Version of drizzle-team/drizzle-orm you run

CompareView on GitHub

Release history

All releases on GitHub
BadgeLatest version of drizzle-team/drizzle-orm[![version](/badge/drizzle-team/drizzle-orm)](/p/drizzle-team/drizzle-orm)

ORM

  • [BREAKING] Fixed postgres-js transparent parsers set by drizzle() constructors breaking driver's own serializers for timestamptz, timestamp, date, time, json, jsonb types (fixes #3171, #4426, #5789) paramsInErrors

:exclamation: Any existing workarounds with manual JSON.stringify(jsonValue) in raw sql or raw driver calls must be removed to prevent double stringification of JSON params; For array-type JSON params in sql use sql.param(jsonArrayValue) to avoid it being parsed as value list instead of param.

  • [BREAKING] Restricted undefined value passed to fields in relational queries' where - now throws an error upon encountering undefined in filters, added EmptyFilter symbol (import { EmptyFilter } from 'drizzle-orm/relations') that can be used as an explicit replacement of undefined where possibly absent filter is desired by design rather than possible bug (fixes #5636)

Example:

    db.query.users.findMany({ where: { isActive: params.isActive ?? EmptyFilter } })
  • [BREAKING] Relation filters without conditions ({}, or containing only empty conditions) are now skipped like any other empty filter instead of generating exists (...) check of relation's presence - use true to filter by relation's presence, false - by its absence

Example:

    // Previously: `where exists (select * from "posts" ...)`, now: no filter
    db.query.users.findMany({ where: { posts: {} } })
    // Users with at least one post
    db.query.users.findMany({ where: { posts: true } })
  • [BREAKING] Updated postgres codecs: now generic codecs contain only in-json codecs (mirroring mysql), contents of drivers' codecs remain unchanged
  • [BREAKING] Switched pg bytea in-json codecs from encode(..., 'base64') casts to decoding to_json's native hex output
  • [BREAKING] Made nested select join nullification consider SQL field data during nullification
  • [BREAKING] Fixed sqlite ignoring .$defaultFn(...) on insert when .default(...) is present
  • [BREAKING] Untied bun-sql/mysql, mysql2, singlestore column mapping from connection config, removed forced bigint params on their respective configs, replaced with more stable cast codecs
  • [BREAKING] Reworked cockroach column builders to mirror pg - now both have same .array('[][]...') syntax
  • [BREAKING] Moved View exports from drizzle-orm/sql/sql to drizzle-orm/view
  • [BREAKING] getTableUniqueName no longer prefixes aliased views or tables with their schema
  • [BREAKING] getTableUniqueName no longer sets public. prefix for entities without schema
  • [BREAKING] Updated View class: switched to Table-like object config for type template, typed schema property
  • [BREAKING] Updated withReplicas (indirectly fixes #4185):
  • Now every query goes to primary db by default
  • To query replica, explicitly call db.$replica
  • [BREAKING] Added withCastCodecs = false switch to getSQL(), withCastCodecs = true switch to toSQL() of non-relational query builders - now db.select(...).from(...).getSQL() emits query without cast codecs by default
  • [BREAKING] Reworked sqlite-proxy:
  • Added rowMode: 'array' | 'object' switch for 'all' | 'get' execute methods
  • Dropped { rows: Result[] } callback result wrapping - now expected direct return of expected data
  • Replaced callback, batchCallback with SqliteProxyExecutors object - must provide run, all, get handlers & optional batch handler
  • Dropped values execute method due to it being duplicate of array-mode all
  • Added TRunResult type inferrence based on return type of run executor, updated SqliteRemoteDatabase template with TRunResult argument
  • Added per-item rowMode: 'array' | 'object' to batch, batch is expected to mirror executors' return types per query
  • [BREAKING] Fixed runtime-type expected result mismatch for get (data | undefined in runtime, data[] in types) (fixes #5461, #3394)
  • [BREAKING] Fixed sqlite db.get(sql) return type lacking | undefined for queries without returned rows
  • [BREAKING] Omitted query params from DrizzleQueryError by default, added paramsInErrors option to drizzle constructor to enable query params in DrizzleQueryError (fixes #5939)

Example:

  const db = drizzle({
    connection: 'postgres://...',
    paramsInErrors: true
  })
  • [BREAKING] For mysql, postgres, cockroach, mssql set RQBv2 to new query build strategy to fix slow query plans (fixes #5245)

Can be opted out of per query via strategy switch: db.query.findMany({ strategy: 'basic' })

When used, may break direct references to relations in raw SQL syntax where, orderBy:

  // posts with the most comments first
  db.query.posts.findMany({
	with: { author: true, comments: true },
	orderBy: (t, { sql }) => sql`json_array_length("comments"."r") desc, ${t.id}`, // "comments" becomes unreachable due to query nesting
	limit: 2,
  });

  // posts of verified authors
  db.query.posts.findMany({
	with: { author: true },
	where: { RAW: (t, { sql }) => sql`("author"."r"->>'verified')::boolean` }, // "author" becomes unreachable due to query nesting
  });
  • [BREAKING] Moved StringChunk, commonStringChunks exports from drizzle-orm/sql/sql to drizzle-orm/sql/common-chunks (still exported from drizzle-orm/sql)
  • [BREAKING] Switched RQBv2 build functions to chunk collection: each accepts optional trailing collectTo: SQLChunk[] array to push chunks to and returns chunk arrays instead of SQL

:exclamation: Chunk arrays embedded into sql directly are rendered as value lists - wrap them in new SQL(chunks) to use them as query parts

  • relationsFilterToSQL(...).sql: SQL | undefined -> SQLChunk[] | undefined, added collectTo parameter

Full release notesCompare with previous