Skip to content

chore(deps): update dependency drizzle-orm to 0.33 || 0.35 - autoclosed

Renovate Bot a demandé de fusionner renovate/drizzle-orm-0.x vers main

This MR contains the following updates:

Package Type Update Change
drizzle-orm (source) peerDependencies minor 0.33 -> 0.33 || 0.35

Release Notes

drizzle-team/drizzle-orm (drizzle-orm)

v0.35.2

Compare Source

  • Fix issues with importing in several environments after updating the Drizzle driver implementation

We've added approximately 240 tests to check the ESM and CJS builds for all the drivers we have. You can check them here

v0.35.1

Compare Source

  • Updated internal versions for the drizzle-kit and drizzle-orm packages. Changes were introduced in the last minor release, and you are required to upgrade both packages to ensure they work as expected

v0.35.0

Compare Source

Important change after 0.34.0 release

Updated the init Drizzle database API

The API from version 0.34.0 turned out to be unusable and needs to be changed. You can read more about our decisions in this discussion

If you still want to use the new API introduced in 0.34.0, which can create driver clients for you under the hood, you can now do so

import { drizzle } from "drizzle-orm/node-postgres";

const db = drizzle(process.env.DATABASE_URL);
// or
const db = drizzle({
  connection: process.env.DATABASE_URL
});
const db = drizzle({
  connection: {
    user: "...",
    password: "...",
    host: "...",
    port: 4321,
    db: "...",
  },
});

// if you need to pass logger or schema
const db = drizzle({
  connection: process.env.DATABASE_URL,
  logger: true,
  schema: schema,
});

in order to not introduce breaking change - we will still leave support for deprecated API until V1 release. It will degrade autocomplete performance in connection params due to DatabaseDriver | ConnectionParams types collision, but that's a decent compromise against breaking changes

import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";

const client = new Pool({ connectionString: process.env.DATABASE_URL });
const db = drizzle(client); // deprecated but available

// new version
const db = drizzle({
  client: client,
});

New Features

New .orderBy() and .limit() functions in update and delete statements SQLite and MySQL

You now have more options for the update and delete query builders in MySQL and SQLite

Example

await db.update(usersTable).set({ verified: true }).limit(2).orderBy(asc(usersTable.name));

await db.delete(usersTable).where(eq(usersTable.verified, false)).limit(1).orderBy(asc(usersTable.name));

New drizzle.mock() function

There were cases where you didn't need to provide a driver to the Drizzle object, and this served as a workaround

const db = drizzle({} as any)

Now you can do this using a mock function

const db = drizzle.mock()

There is no valid production use case for this, but we used it in situations where we needed to check types, etc., without making actual database calls or dealing with driver creation. If anyone was using it, please switch to using mocks now

Internal updates

  • Upgraded TS in codebase to the version 5.6.3

Bug fixes

v0.34.1

Compare Source

  • Fixed dynamic imports for CJS and MJS in the /connect module

v0.34.0

Compare Source

Breaking changes and migrate guide for Turso users

If you are using Turso and libsql, you will need to upgrade your drizzle.config and @libsql/client package.

  1. This version of drizzle-orm will only work with @libsql/client@0.10.0 or higher if you are using the migrate function. For other use cases, you can continue using previous versions(But the suggestion is to upgrade) To install the latest version, use the command:
npm i @​libsql/client@latest
  1. Previously, we had a common drizzle.config for SQLite and Turso users, which allowed a shared strategy for both dialects. Starting with this release, we are introducing the turso dialect in drizzle-kit. We will evolve and improve Turso as a separate dialect with its own migration strategies.

Before

import { defineConfig } from "drizzle-kit";

export default defineConfig({
  dialect: "sqlite",
  schema: "./schema.ts",
  out: "./drizzle",
  dbCredentials: {
    url: "database.db",
  },
  breakpoints: true,
  verbose: true,
  strict: true,
});

After

import { defineConfig } from "drizzle-kit";

export default defineConfig({
  dialect: "turso",
  schema: "./schema.ts",
  out: "./drizzle",
  dbCredentials: {
    url: "database.db",
  },
  breakpoints: true,
  verbose: true,
  strict: true,
});

If you are using only SQLite, you can use dialect: "sqlite"

LibSQL/Turso and Sqlite migration updates

SQLite "generate" and "push" statements updates

Starting from this release, we will no longer generate comments like this:

      '/*\n SQLite does not support "Changing existing column type" out of the box, we do not generate automatic migration for that, so it has to be done manually'
      + '\n Please refer to: https://www.techonthenet.com/sqlite/tables/alter_table.php'
      + '\n                  https://www.sqlite.org/lang_altertable.html'
      + '\n                  https://stackoverflow.com/questions/2083543/modify-a-columns-type-in-sqlite3'
      + "\n\n Due to that we don't generate migration automatically and it has to be done manually"
      + '\n*/'

We will generate a set of statements, and you can decide if it's appropriate to create data-moving statements instead. Here is an example of the SQL file you'll receive now:

PRAGMA foreign_keys=OFF;
--> statement-breakpoint
CREATE TABLE `__new_worker` (
  `id` integer PRIMARY KEY NOT NULL,
  `name` text NOT NULL,
  `salary` text NOT NULL,
  `job_id` integer,
  FOREIGN KEY (`job_id`) REFERENCES `job`(`id`) ON UPDATE no action ON DELETE no action
);
--> statement-breakpoint
INSERT INTO `__new_worker`("id", "name", "salary", "job_id") SELECT "id", "name", "salary", "job_id" FROM `worker`;
--> statement-breakpoint
DROP TABLE `worker`;
--> statement-breakpoint
ALTER TABLE `__new_worker` RENAME TO `worker`;
--> statement-breakpoint
PRAGMA foreign_keys=ON;
LibSQL/Turso "generate" and "push" statements updates

Since LibSQL supports more ALTER statements than SQLite, we can generate more statements without recreating your schema and moving all the data, which can be potentially dangerous for production environments.

LibSQL and Turso will now have a separate dialect in the Drizzle config file, meaning that we will evolve Turso and LibSQL independently from SQLite and will aim to support as many features as Turso/LibSQL offer.

With the updated LibSQL migration strategy, you will have the ability to:

  • Change Data Type: Set a new data type for existing columns.
  • Set and Drop Default Values: Add or remove default values for existing columns.
  • Set and Drop NOT NULL: Add or remove the NOT NULL constraint on existing columns.
  • Add References to Existing Columns: Add foreign key references to existing columns

You can find more information in the LibSQL documentation

LIMITATIONS
  • Dropping foreign key will cause table recreation.

This is because LibSQL/Turso does not support dropping this type of foreign key.

CREATE TABLE `users` (
  `id` integer NOT NULL,
  `name` integer,
  `age` integer PRIMARY KEY NOT NULL
  FOREIGN KEY (`name`) REFERENCES `users1`("id") ON UPDATE no action ON DELETE no action
);
  • If the table has indexes, altering columns will cause index recreation: Drizzle-Kit will drop the indexes, modify the columns, and then create the indexes.

  • Adding or dropping composite foreign keys is not supported and will cause table recreation.

  • Primary key columns can not be altered and will cause table recreation.

  • Altering columns that are part of foreign key will cause table recreation.

NOTES
  • You can create a reference on any column type, but if you want to insert values, the referenced column must have a unique index or primary key.
CREATE TABLE parent(a PRIMARY KEY, b UNIQUE, c, d, e, f);
CREATE UNIQUE INDEX i1 ON parent(c, d);
CREATE INDEX i2 ON parent(e);
CREATE UNIQUE INDEX i3 ON parent(f COLLATE nocase);

CREATE TABLE child1(f, g REFERENCES parent(a));                        -- Ok
CREATE TABLE child2(h, i REFERENCES parent(b));                        -- Ok
CREATE TABLE child3(j, k, FOREIGN KEY(j, k) REFERENCES parent(c, d));  -- Ok
CREATE TABLE child4(l, m REFERENCES parent(e));                        -- Error!
CREATE TABLE child5(n, o REFERENCES parent(f));                        -- Error!
CREATE TABLE child6(p, q, FOREIGN KEY(p, q) REFERENCES parent(b, c));  -- Error!
CREATE TABLE child7(r REFERENCES parent(c));                           -- Error!

NOTE: The foreign key for the table child5 is an error because, although the parent key column has a unique index, the index uses a different collating sequence.

See more: https://www.sqlite.org/foreignkeys.html

A new and easy way to start using drizzle

Current and the only way to do, is to define client yourself and pass it to drizzle

const client = new Pool({ url: '' });
drizzle(client, { logger: true });

But we want to introduce you to a new API, which is a simplified method in addition to the existing one.

Most clients will have a few options to connect, starting with the easiest and most common one, and allowing you to control your client connection as needed.

Let's use node-postgres as an example, but the same pattern can be applied to all other clients

// Finally, one import for all available clients and dialects!
import { drizzle } from 'drizzle-orm/connect'

// Choose a client and use a connection URL — nothing else is needed!
const db1 = await drizzle("node-postgres", process.env.POSTGRES_URL);

// If you need to pass a logger, schema, or other configurations, you can use an object and specify the client-specific URL in the connection
const db2 = await drizzle("node-postgres", {
  connection: process.env.POSTGRES_URL,
  logger: true
});

// And finally, if you need to use full client/driver-specific types in connections, you can use a URL or host/port/etc. as an object inferred from the underlying client connection types
const db3 = await drizzle("node-postgres", {
  connection: {
    connectionString: process.env.POSTGRES_URL,
  },
});

const db4 = await drizzle("node-postgres", {
  connection: {
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    database: process.env.DB_NAME,
    ssl: true,
  },
});

A few clients will have a slightly different API due to their specific behavior. Let's take a look at them:

For aws-data-api-pg, Drizzle will require resourceArn, database, and secretArn, along with any other AWS Data API client types for the connection, such as credentials, region, etc.

drizzle("aws-data-api-pg", {
  connection: {
    resourceArn: "",
    database: "",
    secretArn: "",
  },
});

For d1, the CloudFlare Worker types as described in the documentation here will be required.

drizzle("d1", {
  connection: env.DB // CloudFlare Worker Types
})

For vercel-postgres, nothing is needed since Vercel automatically retrieves the POSTGRES_URL from the .env file. You can check this documentation for more info

drizzle("vercel-postgres")

Note that the first example with the client is still available and not deprecated. You can use it if you don't want to await the drizzle object. The new way of defining drizzle is designed to make it easier to import from one place and get autocomplete for all the available clients

Optional names for columns and callback in drizzle table

We believe that schema definition in Drizzle is extremely powerful and aims to be as close to SQL as possible while adding more helper functions for JS runtime values.

However, there are a few areas that could be improved, which we addressed in this release. These include:

  • Unnecessary database column names when TypeScript keys are essentially just copies of them
  • A callback that provides all column types available for a specific table.

Let's look at an example with PostgreSQL (this applies to all the dialects supported by Drizzle)

Previously

import { boolean, pgTable, text, uuid } from "drizzle-orm/pg-core";
  
export const ingredients = pgTable("ingredients", {
  id: uuid("id").defaultRandom().primaryKey(),
  name: text("name").notNull(),
  description: text("description"),
  inStock: boolean("in_stock").default(true),
});

The previous table definition will still be valid in the new release, but it can be replaced with this instead

import { pgTable } from "drizzle-orm/pg-core";

export const ingredients = pgTable("ingredients", (t) => ({
  id: t.uuid().defaultRandom().primaryKey(),
  name: t.text().notNull(),
  description: t.text(),
  inStock: t.boolean("in_stock").default(true),
}));

New casing param in drizzle-orm and drizzle-kit

There are more improvements you can make to your schema definition. The most common way to name your variables in a database and in TypeScript code is usually snake_case in the database and camelCase in the code. For this case, in Drizzle, you can now define a naming strategy in your database to help Drizzle map column keys automatically. Let's take a table from the previous example and make it work with the new casing API in Drizzle

Table can now become:

import { pgTable } from "drizzle-orm/pg-core";

export const ingredients = pgTable("ingredients", (t) => ({
  id: t.uuid().defaultRandom().primaryKey(),
  name: t.text().notNull(),
  description: t.text(),
  inStock: t.boolean().default(true),
}));

As you can see, inStock doesn't have a database name alias, but by defining the casing configuration at the connection level, all queries will automatically map it to snake_case

const db = await drizzle('node-postgres', { connection: '', casing: 'snake_case' })

For drizzle-kit migrations generation you should also specify casing param in drizzle config, so you can be sure you casing strategy will be applied to drizzle-kit as well

import { defineConfig } from "drizzle-kit";

export default defineConfig({
  dialect: "postgresql",
  schema: "./schema.ts",
  dbCredentials: {
    url: "postgresql://postgres:password@localhost:5432/db",
  },
  casing: "snake_case",
});

New "count" API

Before this release to count entities in a table, you would need to do this:

const res = await db.select({ count: sql`count(*)` }).from(users);
const count = res[0].count;

The new API will look like this:

// how many users are in the database
const count: number = await db.$count(users);

// how many users with the name "Dan" are in the database
const count: number = await db.$count(users, eq(name, "Dan"));

This can also work as a subquery and within relational queries

const users = await db.select({
    ...users,
    postsCount: db.$count(posts, eq(posts.authorId, users.id))
});

const users = await db.query.users.findMany({
    extras: {
        postsCount: db.$count(posts, eq(posts.authorId, users.id))
    }
})

Ability to execute raw strings instead of using SQL templates for raw queries

Previously, you would have needed to do this to execute a raw query with Drizzle

import { sql } from 'drizzle-orm'

db.execute(sql`select * from ${users}`);
// or
db.execute(sql.raw(`select * from ${users}`));

You can now do this as well

db.execute('select * from users')

You can now access the driver client from Drizzle db instance

const client = db.$client;

Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this MR and you won't be reminded about this update again.


  • If you want to rebase/retry this MR, check this box

This MR has been generated by Renovate Bot.

Modification effectuée par Renovate Bot

Rapports de requête de fusion

Chargement en cours