We’ve introduced a lot of changes in this version, and something will definitely break. If anything goes wrong, you can either downgrade to version
1.0.0-beta.1or0.44.7, and please report any issues on GitHub or our Discord!
Don’t forget to check
1.0.0-beta.1release notes as well: https://github.com/drizzle-team/drizzle-orm/blob/beta/changelogs/drizzle-orm/1.0.0-beta.1.md
Check the migration guide for RQBv1 to RQBv2 migration steps: https://orm.drizzle.team/docs/relations-v1-v2
Check new RQBv2 schema docs: https://orm.drizzle.team/docs/relations-v2
Check new RQBv2 query docs: https://orm.drizzle.team/docs/rqb-v2
New Features
MSSQL dialect
Drizzle now supports MSSQL in drizzle-orm, drizzle-kit and drizzle-seed packages. It support most of the columns, query builder capabilities, migration strategies, etc.
The only feature that is not yet supported is RQBv2
// Make sure to install the 'mssql' package
import { drizzle } from 'drizzle-orm/node-mssql';
const db = drizzle(process.env.DATABASE_URL);
const result = await db.execute('select 1');// Make sure to install the 'pg' package
import { drizzle } from 'drizzle-orm/node-mssql';
// You can specify any property from the mssql connection options
const db = drizzle({
connection: {
connectionString: process.env.DATABASE_URL,
ssl: true
}
});
const result = await db.execute('select 1');CockroachDB dialect
Drizzle now supports MSSQL in drizzle-orm, drizzle-kit and drizzle-seed packages. It support most of the columns, query builder capabilities, migration strategies, etc.
The only feature that is not yet supported is RQBv2
// Make sure to install the 'pg' package
import { drizzle } from 'drizzle-orm/cockroach';
const db = drizzle(process.env.DATABASE_URL);
const result = await db.execute('select 1');// Make sure to install the 'pg' package
import { drizzle } from 'drizzle-orm/cockroach';
// You can specify any property from the node-postgres connection options
const db = drizzle({
connection: {
connectionString: process.env.DATABASE_URL,
ssl: true
}
});
const result = await db.execute('select 1');Relational Query Parts
In a case you need to separate relations config into several parts you can use defineRelationsPart helpers
import { defineRelations, defineRelationsPart } from 'drizzle-orm';
import * as schema from "./schema";
export const relations = defineRelations(schema, (r) => ({
users: {
invitee: r.one.users({
from: r.users.invitedBy,
to: r.users.id,
}),
posts: r.many.posts(),
}
}));
export const part = defineRelationsPart(schema, (r) => ({
posts: {
author: r.one.users({
from: r.posts.authorId,
to: r.users.id,
}),
}
}));and then you can provide it to the db instance
const db = drizzle(process.env.DB_URL, { relations: { ...relations, ...part } })Folders v3 migrations
Linked discussion: https://github.com/drizzle-team/drizzle-orm/discussions/2832
We’ve updated the migrations folder structure by:
- removing journal.json
- grouping SQL files and snapshots into separate migration folders
- removing the
drizzle-kit dropcommand
These changes eliminate potential Git conflicts with the journal file and simplify the process of dropping or fixing conflicted migrations
In upcoming beta releases, we’ll introduce commutativity checks to help guide you through team migration conflicts, detect possible collisions, and suggest ways to resolve them
Commutativity discussion: https://github.com/drizzle-team/drizzle-orm/discussions/5005
To migrate previous folders to a new format you would need to run
drizzle-kit upFull drizzle-kit rewrite
Architecture rewrite to close major kit and migration issues. We’ve completed a set of valuable and necessary updates to help us iterate faster, improve test coverage, and enhance overall stability.
Summary of work completed:
- Migrated from database snapshots to database DDL snapshots
- Reworked the entire architecture for detecting and applying diffs
- Added significant improvements for defaults, expressions, and types detection
- Reduced schema introspection time from 10 seconds to under 1 second by minimizing database calls and query complexity
- Added query hints and explain support for push
- Expanded test coverage - each test case now runs up to 6 different scenarios (e.g., push+push, pull+generate, etc.)
Added drizzle-kit pull --init
This flag will create a drizzle migration table in the database and will mark first pulled migration as applied, so you can contrinue iterating from there
schemaFilter behavior update
drizzle-kit will start managing all the schemas defined in your code. If you want to filter them, you can use schemaFilter
Previously, only the public schema was managed unless you explicitly added more schemas to schemaFilter.
It now also supports glob patterns, allowing you to filter schemas in any way you like
.enableRLS() deprecation
Previously to mark PostgreSQL table with RLS enabled you would need to:
// OLD syntax
pgTable('name', {}).enableRLS()We moved this option to a different place
pgTable.withRLS('users', {});Alias directly on columns
You can now add as alias to the column in a simple way:
const query = db
.select({ age: users.age.as('ageOfUser'), id: users.id.as('userId') })
.from(users)
.orderBy(asc(users.id.as('userId')));MySQL new column types
We’ve added a few more MySQL column types:
- blob: https://orm.drizzle.team/docs/column-types/mysql#blob
- tinyblob: https://orm.drizzle.team/docs/column-types/mysql#tinyblob
- mediumblob: https://orm.drizzle.team/docs/column-types/mysql#mediumblob
- longblob: https://orm.drizzle.team/docs/column-types/mysql#longblob
More Updates and Fixes
- Fixed pg-native Pool detection in node-postgres transactions
- Allowed subqueries in select fields
- Updated typo algorythm => algorithm
- Fixed
$onUpdatenot handlingSQLvalues (fixes #2388, tests implemented by L-Mario564 in #2911) - Fixed
pgmappers not handlingDateinstances inbun-sql:postgresqldriver responses fordate,timestamptypes (fixes #4493)
Bugs fixed
This list is not full, we just had a time to get through some of the issues. This list will be updated through the next few weeks
-
[BUG]: Drizzle-kit pulls postgres functions as Typescript methods
-
[BUG]: When setting the casing to snake_case, the constraint name for unique fields isn’t converted
-
[BUG]:
drizzle-kit pushappendDROP SCHEMAat the end for other schema name -
[BUG]: MySQL enum defaults with value ‘0’ are ignored during introspection
-
[BUG]: bunx drizzle-kit push Freezes at “Reading config file” in Version ^0.31.4
-
[BUG]: Introspect generated files don’t show columns in Views as arrays
-
[BUG]:
drizzle-kit introspectempty''mysqlEnum nad default introspect error -
[BUG]: CHECK constraints with operator functions generate invalid SQL with parameterized values
-
[BUG]: tinyint, bigint doesn’t include when run drizzle-kit pull
-
[BUG]:drizzle-kit pull missing one ’ letter column with default empty text
-
[BUG]: Unable to create composite foreign key: order of SQL statements [Postgres]
-
[BUG]: drizzle-kit MySQL Serializer doesn’t see PKs and CHECK constraints
-
[BUG]: unique key names for multiple columns doesn’t respect casing configuration
-
[BUG]:
drizzle-kit generategenerates out of order/ incorrect migrations -
[BUG]: Drizzle not pulling foreign key names using introspect command in ts + mysql
-
[BUG]: Invalid SQL query generated for MySQL when using “with” feature
-
[BUG]: with Relation in findMany Returns Flattened Array Instead of Key-Value Object
-
[BUG]: drizzle-orm@beta query object is empty in NuxtHub project
-
[BUG]: Big int precision loss when data fetched with json_agg
-
[BUG]: Incorrect column types when using
withfor table created with helper function -
[BUG]: Identifier is too long (should not exceed 63 characters)
-
[BUG]: Drizzle type inferrence doesn’t work properly with many tables
-
[BUG]: drizzle-kit generate when dropping table attempts to delete already deleted constraint
-
[BUG]: Incomplete inferred result type in query API when using optional columns
-
SQLite columns are not marked as unique, instead a unique index has been created
-
[BUG]:Error Typescript for query where in relation (version “drizzle-orm”: “^0.38.3”)
-
[BUG]: findFirst not return undefined or null when not data is found.
-
[BUG]: Type error when performing filter select according to docs
-
[BUG]: Incorrect Non-Nullable Type Inference for One-to-One Related Entities
-
[BUG]: Custom types not working when insert with onConflictDoUpdate in Sqlite
-
[BUG]: Drizzle-kit no longer supporting the special characters in enum values (MySQL)
-
[BUG]:push creates duplicate statements for unique column index
-
[BUG]: TypeError: Cannot read properties of undefined (reading ‘columns’)
-
push:mysql fails to drop a serial column and replace with another column type
-
Drizzle Studio giving error due to
CURRENT_TIMESTAMPin schema -
[BUG]: Mysql new .unique().notNull(),
add constraintis put beforeadd column, throwing error. -
There are three cases where drizzle-kit’s introspect:mysql does not work.
-
[BUG]:
findMany/findFirstincorrectly substituting table names in sql operator -
[BUG]: Incorrect bigint value retrieval using findMany with relations (postgresql)
-
[BUG]: Pressing
escapewhile in thepushconfirmation dialog runs the push -
[BUG]: arrayContains, arrayContained, arrayOverlaps aren’t there in queries find callbacks
-
[BUG]: UUID Error on push, but no issue via generate / migrate
-
[BUG]: default value in migration generates invalid sql.ts file
-
[BUG]: drizzle-kit triggers a _ZodError when uniqueIndex is used together with sql lower
-
[BUG]: drizzle-kit introspect TypeError: Cannot read properties of null (reading ‘camelCase’)
-
[BUG]: Types aren’t correctly inferred for nested
with: { where }clauses -
[BUG]: drizzle-kit introspection does not import “bigint” type when introspecting a MySql database.
-
[BUG]: migrations do not work - table already exists - ER_TABLE_EXISTS_ERROR - mysql
-
[BUG]: Do statement double dollar sign not escaping cases where you want a ”$” as a value
-
[BUG]: PG Numeric inferred as string, but is numeric at runtime
-
[BUG]: Unique key reconciliation with upstream schema is inconsistent
-
[BUG]: Aggregated results from many-to-one relations doesn’t return timestamp using postgres DB
-
[BUG]: Issues with nested conditions & placeholders in SQLite query
-
[BUG]: Geometry config type doesn’t appear to affect the output sql
-
[BUG]: relation query API default alias is different than regular alias
-
[BUG]: Typing issue when using tables with the same name across different schemas
-
[BUG]: Timestamp formatted differently if fetched as relation rather than directly
-
[BUG]: Adding new column and unique key on the new column generates invalid migration file
-
[BUG]: Query API does not include schema name when including child relations
-
[BUG]: Planetscale got packets out of order for ‘serial’ type on push
-
[BUG]: on cascade delete issue with multiple foreign keys and migrations
-
[BUG]: Schema name is not prepended to the table name when aliased const.
-
[BUG]:
Do not know how to serialize a BigInterrors when using BigInt indefault(0n)directive -
[BUG]: sql“ interpolates the wrong table name when used in extras
-
[FEATURE]: infer possible undefined columns value if is a boolean (not specifically true or false)
-
[BUG]: ER_WRONG_AUTO_KEY - Drizzle Kit not detecting primary keys
-
[BUG]: Unable to use orderBy clause on multiple relations when placed adjacently in a query (MySQL)
-
[BUG]: wrong typeHint when using relations (one and automatic limit: 1)
-
[BUG]:
columnspartial select gives bad type with dynamic conditions -
[BUG]:
mapWithisn’t working onextraswhen doing relational queries withfindFirstorfindMany -
[BUG]:
findFirstandfindManyisn’t correctly setting the table name when using sql directive -
[FEATURE]: Add back filtering by nested relations in relational queries
-
[BUG]: where clause on relational query overwrites the table name
-
[BUG]: error: column “role” cannot be cast automatically to type user_role
-
[BUG]: Relations inferring incorrect table with non-default Postgres schema
-
[BUG]: Relational queries break customTypes with underlying DECIMAL dataTypes
-
[BUG]: Relational query on sqlite/d1 with order-by has issues
-
Allow referencing deeply nested properties in relational queries
-
[BUG]: planetscale - now() and current_timestamp() doesn’t work when FSP is specified for timestamp
-
[BUG]: MySQL alter table fails where tablename is reserved word