Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build(deps): update dependency drizzle-orm to v0.36.4 #702

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

renovate[bot]
Copy link
Contributor

@renovate renovate bot commented Mar 30, 2024

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
drizzle-orm (source) 0.31.0 -> 0.36.4 age adoption passing confidence

Release Notes

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

v0.36.4

Compare Source

New Package: drizzle-seed

[!NOTE]
drizzle-seed can only be used with [email protected] or higher. Versions lower than this may work at runtime but could have type issues and identity column issues, as this patch was introduced in [email protected]

Full Reference

The full API reference and package overview can be found in our official documentation

Basic Usage

In this example we will create 10 users with random names and ids

import { pgTable, integer, text } from "drizzle-orm/pg-core";
import { drizzle } from "drizzle-orm/node-postgres";
import { seed } from "drizzle-seed";

const users = pgTable("users", {
  id: integer().primaryKey(),
  name: text().notNull(),
});

async function main() {
  const db = drizzle(process.env.DATABASE_URL!);
  await seed(db, { users });
}

main();

Options

count

By default, the seed function will create 10 entities.
However, if you need more for your tests, you can specify this in the seed options object

await seed(db, schema, { count: 1000 });

seed

If you need a seed to generate a different set of values for all subsequent runs, you can define a different number
in the seed option. Any new number will generate a unique set of values

await seed(db, schema, { seed: 12345 });

The full API reference and package overview can be found in our official documentation

Features

Added OVERRIDING SYSTEM VALUE api to db.insert()

If you want to force you own values for GENERATED ALWAYS AS IDENTITY columns, you can use OVERRIDING SYSTEM VALUE

As PostgreSQL docs mentions

In an INSERT command, if ALWAYS is selected, a user-specified value is only accepted if the INSERT statement specifies OVERRIDING SYSTEM VALUE. If BY DEFAULT is selected, then the user-specified value takes precedence

await db.insert(identityColumnsTable).overridingSystemValue().values([
  { alwaysAsIdentity: 2 },
]);

Added .$withAuth() API for Neon HTTP driver

Using this API, Drizzle will send you an auth token to authorize your query. It can be used with any query available in Drizzle by simply adding .$withAuth() before it. This token will be used for a specific query

Examples

const token = 'HdncFj1Nm'

await db.$withAuth(token).select().from(usersTable);
await db.$withAuth(token).update(usersTable).set({ name: 'CHANGED' }).where(eq(usersTable.name, 'TARGET'))

Bug Fixes

v0.36.3

Compare Source

New Features

Support for UPDATE ... FROM in PostgreSQL and SQLite

As the SQLite documentation mentions:

[!NOTE]
The UPDATE-FROM idea is an extension to SQL that allows an UPDATE statement to be driven by other tables in the database.
The "target" table is the specific table that is being updated. With UPDATE-FROM you can join the target table
against other tables in the database in order to help compute which rows need updating and what
the new values should be on those rows

Similarly, the PostgreSQL documentation states:

[!NOTE]
A table expression allowing columns from other tables to appear in the WHERE condition and update expressions

Drizzle also supports this feature starting from this version

For example, current query:

await db
  .update(users)
  .set({ cityId: cities.id })
  .from(cities)
  .where(and(eq(cities.name, 'Seattle'), eq(users.name, 'John')))

Will generate this sql

update "users" set "city_id" = "cities"."id" 
from "cities" 
where ("cities"."name" = $1 and "users"."name" = $2)

-- params: [ 'Seattle', 'John' ]

You can also alias tables that are joined (in PG, you can also alias the updating table too).

const c = alias(cities, 'c');
await db
  .update(users)
  .set({ cityId: c.id })
  .from(c);

Will generate this sql

update "users" set "city_id" = "c"."id" 
from "cities" "c"

In PostgreSQL, you can also return columns from the joined tables.

const updatedUsers = await db
  .update(users)
  .set({ cityId: cities.id })
  .from(cities)
  .returning({ id: users.id, cityName: cities.name });

Will generate this sql

update "users" set "city_id" = "cities"."id" 
from "cities" 
returning "users"."id", "cities"."name"

Support for INSERT INTO ... SELECT in all dialects

As the SQLite documentation mentions:

[!NOTE]
The second form of the INSERT statement contains a SELECT statement instead of a VALUES clause.
A new entry is inserted into the table for each row of data returned by executing the SELECT statement.
If a column-list is specified, the number of columns in the result of the SELECT must be the same as
the number of items in the column-list. Otherwise, if no column-list is specified, the number of
columns in the result of the SELECT must be the same as the number of columns in the table.
Any SELECT statement, including compound SELECTs and SELECT statements with ORDER BY and/or LIMIT clauses,
may be used in an INSERT statement of this form.

[!CAUTION]
To avoid a parsing ambiguity, the SELECT statement should always contain a WHERE clause, even if that clause is simply "WHERE true", if the upsert-clause is present. Without the WHERE clause, the parser does not know if the token "ON" is part of a join constraint on the SELECT, or the beginning of the upsert-clause.

As the PostgreSQL documentation mentions:

[!NOTE]
A query (SELECT statement) that supplies the rows to be inserted

And as the MySQL documentation mentions:

[!NOTE]
With INSERT ... SELECT, you can quickly insert many rows into a table from the result of a SELECT statement, which can select from one or many tables

Drizzle supports the current syntax for all dialects, and all of them share the same syntax. Let's review some common scenarios and API usage.
There are several ways to use select inside insert statements, allowing you to choose your preferred approach:

  • You can pass a query builder inside the select function.
  • You can use a query builder inside a callback.
  • You can pass an SQL template tag with any custom select query you want to use

Query Builder

const insertedEmployees = await db
  .insert(employees)
  .select(
    db.select({ name: users.name }).from(users).where(eq(users.role, 'employee'))
  )
  .returning({
    id: employees.id,
    name: employees.name
  });
const qb = new QueryBuilder();
await db.insert(employees).select(
    qb.select({ name: users.name }).from(users).where(eq(users.role, 'employee'))
);

Callback

await db.insert(employees).select(
    () => db.select({ name: users.name }).from(users).where(eq(users.role, 'employee'))
);
await db.insert(employees).select(
    (qb) => qb.select({ name: users.name }).from(users).where(eq(users.role, 'employee'))
);

SQL template tag

await db.insert(employees).select(
    sql`select "users"."name" as "name" from "users" where "users"."role" = 'employee'`
);
await db.insert(employees).select(
    () => sql`select "users"."name" as "name" from "users" where "users"."role" = 'employee'`
);

v0.36.2

Compare Source

New Features
Bug and typo fixes

v0.36.1

Compare Source

Bug Fixes

v0.36.0

Compare Source

This version of drizzle-orm requires [email protected] to enable all new features

New Features

Row-Level Security (RLS)

With Drizzle, you can enable Row-Level Security (RLS) for any Postgres table, create policies with various options, and define and manage the roles those policies apply to.

Drizzle supports a raw representation of Postgres policies and roles that can be used in any way you want. This works with popular Postgres database providers such as Neon and Supabase.

In Drizzle, we have specific predefined RLS roles and functions for RLS with both database providers, but you can also define your own logic.

Enable RLS

If you just want to enable RLS on a table without adding policies, you can use .enableRLS()

As mentioned in the PostgreSQL documentation:

If no policy exists for the table, a default-deny policy is used, meaning that no rows are visible or can be modified.
Operations that apply to the whole table, such as TRUNCATE and REFERENCES, are not subject to row security.

import { integer, pgTable } from 'drizzle-orm/pg-core';

export const users = pgTable('users', {
	id: integer(),
}).enableRLS();

If you add a policy to a table, RLS will be enabled automatically. So, there’s no need to explicitly enable RLS when adding policies to a table.

Roles

Currently, Drizzle supports defining roles with a few different options, as shown below. Support for more options will be added in a future release.

import { pgRole } from 'drizzle-orm/pg-core';

export const admin = pgRole('admin', { createRole: true, createDb: true, inherit: true });

If a role already exists in your database, and you don’t want drizzle-kit to ‘see’ it or include it in migrations, you can mark the role as existing.

import { pgRole } from 'drizzle-orm/pg-core';

export const admin = pgRole('admin').existing();
Policies

To fully leverage RLS, you can define policies within a Drizzle table.

In PostgreSQL, policies should be linked to an existing table. Since policies are always associated with a specific table, we decided that policy definitions should be defined as a parameter of pgTable

Example of pgPolicy with all available properties

import { sql } from 'drizzle-orm';
import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core';

export const admin = pgRole('admin');

export const users = pgTable('users', {
	id: integer(),
}, (t) => [
	pgPolicy('policy', {
		as: 'permissive',
		to: admin,
		for: 'delete',
		using: sql``,
		withCheck: sql``,
	}),
]);

Link Policy to an existing table

There are situations where you need to link a policy to an existing table in your database.
The most common use case is with database providers like Neon or Supabase, where you need to add a policy
to their existing tables. In this case, you can use the .link() API

import { sql } from "drizzle-orm";
import { pgPolicy } from "drizzle-orm/pg-core";
import { authenticatedRole, realtimeMessages } from "drizzle-orm/supabase";

export const policy = pgPolicy("authenticated role insert policy", {
  for: "insert",
  to: authenticatedRole,
  using: sql``,
}).link(realtimeMessages);
Migrations

If you are using drizzle-kit to manage your schema and roles, there may be situations where you want to refer to roles that are not defined in your Drizzle schema. In such cases, you may want drizzle-kit to skip managing these roles without having to define each role in your drizzle schema and marking it with .existing().

In these cases, you can use entities.roles in drizzle.config.ts. For a complete reference, refer to the the drizzle.config.ts documentation.

By default, drizzle-kit does not manage roles for you, so you will need to enable this feature in drizzle.config.ts.

// drizzle.config.ts
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  dialect: 'postgresql',
  schema: "./drizzle/schema.ts",
  dbCredentials: {
    url: process.env.DATABASE_URL!
  },
  verbose: true,
  strict: true,
  entities: {
    roles: true
  }
});

In case you need additional configuration options, let's take a look at a few more examples.

You have an admin role and want to exclude it from the list of manageable roles

// drizzle.config.ts
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  ...
  entities: {
    roles: {
      exclude: ['admin']
    }
  }
});

You have an admin role and want to include it in the list of manageable roles

// drizzle.config.ts
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  ...
  entities: {
    roles: {
      include: ['admin']
    }
  }
});

If you are using Neon and want to exclude Neon-defined roles, you can use the provider option

// drizzle.config.ts
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  ...
  entities: {
    roles: {
      provider: 'neon'
    }
  }
});

If you are using Supabase and want to exclude Supabase-defined roles, you can use the provider option

// drizzle.config.ts
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  ...
  entities: {
    roles: {
      provider: 'supabase'
    }
  }
});

You may encounter situations where Drizzle is slightly outdated compared to new roles specified by your database provider.
In such cases, you can use the provider option and exclude additional roles:

// drizzle.config.ts
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  ...
  entities: {
    roles: {
      provider: 'supabase',
      exclude: ['new_supabase_role']
    }
  }
});
RLS on views

With Drizzle, you can also specify RLS policies on views. For this, you need to use security_invoker in the view's WITH options. Here is a small example:

...

export const roomsUsersProfiles = pgView("rooms_users_profiles")
  .with({
    securityInvoker: true,
  })
  .as((qb) =>
    qb
      .select({
        ...getTableColumns(roomsUsers),
        email: profiles.email,
      })
      .from(roomsUsers)
      .innerJoin(profiles, eq(roomsUsers.userId, profiles.id))
  );
Using with Neon

The Neon Team helped us implement their vision of a wrapper on top of our raw policies API. We defined a specific
/neon import with the crudPolicy function that includes predefined functions and Neon's default roles.

Here's an example of how to use the crudPolicy function:

import { crudPolicy } from 'drizzle-orm/neon';
import { integer, pgRole, pgTable } from 'drizzle-orm/pg-core';

export const admin = pgRole('admin');

export const users = pgTable('users', {
	id: integer(),
}, (t) => [
	crudPolicy({ role: admin, read: true, modify: false }),
]);

This policy is equivalent to:

import { sql } from 'drizzle-orm';
import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core';

export const admin = pgRole('admin');

export const users = pgTable('users', {
	id: integer(),
}, (t) => [
	pgPolicy(`crud-${admin.name}-policy-insert`, {
		for: 'insert',
		to: admin,
		withCheck: sql`false`,
	}),
	pgPolicy(`crud-${admin.name}-policy-update`, {
		for: 'update',
		to: admin,
		using: sql`false`,
		withCheck: sql`false`,
	}),
	pgPolicy(`crud-${admin.name}-policy-delete`, {
		for: 'delete',
		to: admin,
		using: sql`false`,
	}),
	pgPolicy(`crud-${admin.name}-policy-select`, {
		for: 'select',
		to: admin,
		using: sql`true`,
	}),
]);

Neon exposes predefined authenticated and anaonymous roles and related functions. If you are using Neon for RLS, you can use these roles, which are marked as existing, and the related functions in your RLS queries.

// drizzle-orm/neon
export const authenticatedRole = pgRole('authenticated').existing();
export const anonymousRole = pgRole('anonymous').existing();

export const authUid = (userIdColumn: AnyPgColumn) => sql`(select auth.user_id() = ${userIdColumn})`;

For example, you can use the Neon predefined roles and functions like this:

import { sql } from 'drizzle-orm';
import { authenticatedRole } from 'drizzle-orm/neon';
import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core';

export const admin = pgRole('admin');

export const users = pgTable('users', {
	id: integer(),
}, (t) => [
	pgPolicy(`policy-insert`, {
		for: 'insert',
		to: authenticatedRole,
		withCheck: sql`false`,
	}),
]);
Using with Supabase

We also have a /supabase import with a set of predefined roles marked as existing, which you can use in your schema.
This import will be extended in a future release with more functions and helpers to make using RLS and Supabase simpler.

// drizzle-orm/supabase
export const anonRole = pgRole('anon').existing();
export const authenticatedRole = pgRole('authenticated').existing();
export const serviceRole = pgRole('service_role').existing();
export const postgresRole = pgRole('postgres_role').existing();
export const supabaseAuthAdminRole = pgRole('supabase_auth_admin').existing();

For example, you can use the Supabase predefined roles like this:

import { sql } from 'drizzle-orm';
import { serviceRole } from 'drizzle-orm/supabase';
import { integer, pgPolicy, pgRole, pgTable } from 'drizzle-orm/pg-core';

export const admin = pgRole('admin');

export const users = pgTable('users', {
	id: integer(),
}, (t) => [
	pgPolicy(`policy-insert`, {
		for: 'insert',
		to: serviceRole,
		withCheck: sql`false`,
	}),
]);

The /supabase import also includes predefined tables and functions that you can use in your application

// drizzle-orm/supabase

const auth = pgSchema('auth');
export const authUsers = auth.table('users', {
	id: uuid().primaryKey().notNull(),
});

const realtime = pgSchema('realtime');
export const realtimeMessages = realtime.table(
	'messages',
	{
		id: bigserial({ mode: 'bigint' }).primaryKey(),
		topic: text().notNull(),
		extension: text({
			enum: ['presence', 'broadcast', 'postgres_changes'],
		}).notNull(),
	},
);

export const authUid = sql`(select auth.uid())`;
export const realtimeTopic = sql`realtime.topic()`;

This allows you to use it in your code, and Drizzle Kit will treat them as existing databases,
using them only as information to connect to other entities

import { foreignKey, pgPolicy, pgTable, text, uuid } from "drizzle-orm/pg-core";
import { sql } from "drizzle-orm/sql";
import { authenticatedRole, authUsers } from "drizzle-orm/supabase";

export const profiles = pgTable(
  "profiles",
  {
    id: uuid().primaryKey().notNull(),
    email: text().notNull(),
  },
  (table) => [
    foreignKey({
      columns: [table.id],
	  // reference to the auth table from Supabase
      foreignColumns: [authUsers.id],
      name: "profiles_id_fk",
    }).onDelete("cascade"),
    pgPolicy("authenticated can view all profiles", {
      for: "select",
	  // using predefined role from Supabase
      to: authenticatedRole,
      using: sql`true`,
    }),
  ]
);

Let's check an example of adding a policy to a table that exists in Supabase

import { sql } from "drizzle-orm";
import { pgPolicy } from "drizzle-orm/pg-core";
import { authenticatedRole, realtimeMessages } from "drizzle-orm/supabase";

export const policy = pgPolicy("authenticated role insert policy", {
  for: "insert",
  to: authenticatedRole,
  using: sql``,
}).link(realtimeMessages);

Bug fixes

v0.35.3

Compare Source

New LibSQL driver modules

Drizzle now has native support for all @libsql/client driver variations:

  1. @libsql/client - defaults to node import, automatically changes to web if target or platform is set for bundler, e.g. esbuild --platform=browser
import { drizzle } from 'drizzle-orm/libsql';

const db = drizzle({ connection: {
  url: process.env.DATABASE_URL, 
  authToken: process.env.DATABASE_AUTH_TOKEN 
}});
  1. @libsql/client/node node compatible module, supports :memory:, file, wss, http and turso connection protocols
import { drizzle } from 'drizzle-orm/libsql/node';

const db = drizzle({ connection: {
  url: process.env.DATABASE_URL, 
  authToken: process.env.DATABASE_AUTH_TOKEN 
}});
  1. @libsql/client/web module for fullstack web frameworks like next, nuxt, astro, etc.
import { drizzle } from 'drizzle-orm/libsql/web';

const db = drizzle({ connection: {
  url: process.env.DATABASE_URL, 
  authToken: process.env.DATABASE_AUTH_TOKEN 
}});
  1. @libsql/client/http module for http and https connection protocols
import { drizzle } from 'drizzle-orm/libsql/http';

const db = drizzle({ connection: {
  url: process.env.DATABASE_URL, 
  authToken: process.env.DATABASE_AUTH_TOKEN 
}});
  1. @libsql/client/ws module for ws and wss connection protocols
import { drizzle } from 'drizzle-orm/libsql/ws';

const db = drizzle({ connection: {
  url: process.env.DATABASE_URL, 
  authToken: process.env.DATABASE_AUTH_TOKEN 
}});
  1. @libsql/client/sqlite3 module for :memory: and file connection protocols
import { drizzle } from 'drizzle-orm/libsql/wasm';

const db = drizzle({ connection: {
  url: process.env.DATABASE_URL, 
  authToken: process.env.DATABASE_AUTH_TOKEN 
}});
  1. @libsql/client-wasm Separate experimental package for WASM
import { drizzle } from 'drizzle-orm/libsql';

const db = drizzle({ connection: {
  url: process.env.DATABASE_URL, 
  authToken: process.env.DATABASE_AUTH_TOKEN 
}});

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/[email protected] 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;

v0.33.0

Compare Source

Breaking changes (for some of postgres.js users)

Bugs fixed for this breaking change

As we are doing with other drivers, we've changed the behavior of PostgreSQL-JS to pass raw JSON values, the same as you see them in the database. So if you are using the PostgreSQL-JS driver and passing data to Drizzle elsewhere, please check the new behavior of the client after it is passed to Drizzle.

We will update it to ensure it does not override driver behaviors, but this will be done as a complex task for everything in Drizzle in other releases

If you were using postgres-js with jsonb fields, you might have seen stringified objects in your database, while drizzle insert and select operations were working as expected.

You need to convert those fields from strings to actual JSON objects. To do this, you can use the following query to update your database:

if you are using jsonb:

update table_name
set jsonb_column = (jsonb_column #>> '{}')::jsonb;

if you are using json:

update table_name
set json_column = (json_column #>> '{}')::json;

We've tested it in several cases, and it worked well, but only if all stringified objects are arrays or objects. If you have primitives like strings, numbers, booleans, etc., you can use this query to update all the fields

if you are using jsonb:

UPDATE table_name
SET jsonb_column = CASE
    -- Convert to JSONB if it is a valid JSON object or array
    WHEN jsonb_column #>> '{}' LIKE '{%' OR jsonb_column #>> '{}' LIKE '[%' THEN
        (jsonb_column #>> '{}')::jsonb
    ELSE
        jsonb_column
END
WHERE
    jsonb_column IS NOT NULL;

if you are using json:

UPDATE table_name
SET json_column = CASE
    -- Convert to JSON if it is a valid JSON object or array
    WHEN json_column #>> '{}' LIKE '{%' OR json_column #>> '{}' LIKE '[%' THEN
        (json_column #>> '{}')::json
    ELSE
        json_column
END
WHERE json_column IS NOT NULL;

If nothing works for you and you are blocked, please reach out to me @​AndriiSherman. I will try to help you!

Bug Fixes

v0.32.2

Compare Source

  • Fix AWS Data API type hints bugs in RQB
  • Fix set transactions in MySQL bug - thanks @​roguesherlock
  • Add forwaring dependencies within useLiveQuery, fixes #​2651 - thanks @​anstapol
  • Export additional types from SQLite package, like AnySQLiteUpdate - thanks @​veloii

v0.32.1

Compare Source

  • Fix typings for indexes and allow creating indexes on 3+ columns mixing columns and expressions - thanks @​lbguilherme!
  • Added support for "limit 0" in all dialects - closes #​2011 - thanks @​sillvva!
  • Make inArray and notInArray accept empty list, closes #​1295 - thanks @​RemiPeruto!
  • fix typo in lt typedoc - thanks @​dalechyn!
  • fix wrong example in README.md - thanks @​7flash!

v0.32.0

Compare Source

Release notes for [email protected] and [email protected]

It's not mandatory to upgrade both packages, but if you want to use the new features in both queries and migrations, you will need to upgrade both packages

New Features

🎉 MySQL $returningId() function

MySQL itself doesn't have native support for RETURNING after using INSERT. There is only one way to do it for primary keys with autoincrement (or serial) types, where you can access insertId and affectedRows fields. We've prepared an automatic way for you to handle such cases with Drizzle and automatically receive all inserted IDs as separate objects

import { boolean, int, text, mysqlTable } from 'drizzle-orm/mysql-core';

const usersTable = mysqlTable('users', {
  id: int('id').primaryKey(),
  name: text('name').notNull(),
  verified: boolean('verified').notNull().default(false),
});

const result = await db.insert(usersTable).values([{ name: 'John' }, { name: 'John1' }]).$returningId();
//    ^? { id: number }[]

Also with Drizzle, you can specify a primary key with $default function that will generate custom primary keys at runtime. We will also return those generated keys for you in the $returningId() call

import { varchar, text, mysqlTable } from 'drizzle-orm/mysql-core';
import { createId } from '@​paralleldrive/cuid2';

const usersTableDefFn = mysqlTable('users_default_fn', {
  customId: varchar('id', { length: 256 }).primaryKey().$defaultFn(createId),
  name: text('name').notNull(),
});

const result = await db.insert(usersTableDefFn).values([{ name: 'John' }, { name: 'John1' }]).$returningId();
//  ^? { customId: string }[]

If there is no primary keys -> type will be {}[] for such queries

🎉 PostgreSQL Sequences

You can now specify sequences in Postgres within any schema you need and define all the available properties

Example
import { pgSchema, pgSequence } from "drizzle-orm/pg-core";

// No params specified
export const customSequence = pgSequence("name");

// Sequence with params
export const customSequence = pgSequence("name", {
      startWith: 100,
      maxValue: 10000,
      minValue: 100,
      cycle: true,
      cache: 10,
      increment: 2
});

// Sequence in custom schema
export const customSchema = pgSchema('custom_schema');

export const customSequence = customSchema.sequence("name");
🎉 PostgreSQL Identity Columns

Source: As mentioned, the serial type in Postgres is outdated and should be deprecated. Ideally, you should not use it. Identity columns are the recommended way to specify sequences in your schema, which is why we are introducing the identity columns feature

Example
import { pgTable, integer, text } from 'drizzle-orm/pg-core' 

export const ingredients = pgTable("ingredients", {
  id: integer("id").primaryKey().generatedAlwaysAsIdentity({ startWith: 1000 }),
  name: text("name").notNull(),
  description: text("description"),
});

You can specify all properties available for sequences in the .generatedAlwaysAsIdentity() function. Additionally, you can specify custom names for these sequences

PostgreSQL docs reference.

🎉 PostgreSQL Generated Columns

You can now specify generated columns on any column supported by PostgreSQL to use with generated columns

Example with generated column for tsvector

Note: we will add tsVector column type before latest release

import { SQL, sql } from "drizzle-orm";
import { customType, index, integer, pgTable, text } from "drizzle-orm/pg-core";

const tsVector = customType<{ data: string }>({
  dataType() {
    return "tsvector";
  },
});

export const test = pgTable(
  "test",
  {
    id: integer("id").primaryKey().generatedAlwaysAsIdentity(),
    content: text("content"),
    contentSearch: tsVector("content_search", {
      dimensions: 3,
    }).generatedAlwaysAs(
      (): SQL => sql`to_tsvector('english', ${test.content})`
    ),
  },
  (t) => ({
    idx: index("idx_content_search").using("gin", t.contentSearch),
  })
);

In case you don't need to reference any columns from your table, you can use just sql template or a string

export const users = pgTable("users", {
  id: integer("id"),
  name: text("name"),
  generatedName: text("gen_name").generatedAlwaysAs(sql`hello world!`),
  generatedName1: text("gen_name1").generatedAlwaysAs("hello world!"),
}),
🎉 MySQL Generated Columns

You can now specify generated columns on any column supported by MySQL to use with generated columns

You can specify both stored and virtual options, for more info you can check MySQL docs

Also MySQL has a few limitation for such columns usage, which is described here

Drizzle Kit will also have limitations for push command:

  1. You can't change the generated constraint expression and type using push. Drizzle-kit will ignore this change. To make it work, you would need to drop the column, push, and then add a column with a new expression. This was done due to the complex mapping from the database side, where the schema expression will be modified on the database side and, on introspection, we will get a different string. We can't be sure if you changed this expression or if it was changed and formatted by the database. As long as these are generated columns and push is mostly used for prototyping on a local database, it should be fast to drop and create generated columns. Since these columns are generated, all the data will be restored

  2. generate should have no limitations

Example
export const users = mysqlTable("users", {
  id: int("id"),
  id2: int("id2"),
  name: text("name"),
  generatedName: text("gen_name").generatedAlwaysAs(
    (): SQL => sql`${schema2.users.name} || 'hello'`,
    { mode: "stored" }
  ),
  generatedName1: text("gen_name1").generatedAlwaysAs(
    (): SQL => sql`${schema2.users.name} || 'hello'`,
    { mode: "virtual" }
  ),
}),

In case you don't need to reference any columns from your table, you can use just sql template or a string in .generatedAlwaysAs()

🎉 SQLite Generated Columns

You can now specify generated columns on any column supported by SQLite to use with generated columns

You can specify both stored and virtual options, for more info you can check SQLite docs

Also SQLite has a few limitation for such columns usage, which is described here

Drizzle Kit will also have limitations for push and generate command:

  1. You can't change the generated constraint expression with the stored type in an existing table. You would need to delete this table and create it again. This is due to SQLite limitations for such actions. We will handle this case in future releases (it will involve the creation of a new table with data migration).

  2. You can't add a stored generated expression to an existing column for the same reason as above. However, you can add a virtual expression to an existing column.

  3. You can't change a stored generated expression in an existing column for the same reason as above. However, you can change a virtual expression.

  4. You can't change the generated constraint type from virtual to stored for the same reason as above. However, you can change from stored to virtual.

New Drizzle Kit features

🎉 Migrations support for all the new orm features

PostgreSQL sequences, identity columns and generated columns for all dialects

🎉 New flag --force for drizzle-kit push

You can auto-accept all data-loss statements using the push command. It's only available in CLI parameters. Make sure you always use it if you are fine with running data-loss statements on your database

🎉 New migrations flag prefix

You can now customize migration file prefixes to make the format suitable for your migration tools:

  • index is the default type and will result in 0001_name.sql file names;
  • supabase and timestamp are equal and will result in 20240627123900_name.sql file names;
  • unix will result in unix seconds prefixes 1719481298_name.sql file names;
  • none will omit the prefix completely;
Example: Supabase migrations format
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  dialect: "postgresql",
  migrations: {
    prefix: 'supabase'
  }
});

v0.31.4

Compare Source

  • Mark prisma clients package as optional - thanks @​Cherry

v0.31.3

Compare Source

Bug fixed
  • 🛠️ Fixed RQB behavior for tables with same names in different schemas
  • 🛠️ Fixed [BUG]: Mismatched type hints when using RDS Data API - #​2097
New Prisma-Drizzle extension
import { PrismaClient } from '@&#8203;prisma/client';
import { drizzle } from 'drizzle-orm/prisma/pg';
import { User } from './drizzle';

const prisma = new PrismaClient().$extends(drizzle());
const users = await prisma.$drizzle.select().from(User);

For more info, check docs: https://orm.drizzle.team/docs/prisma

v0.31.2

Compare Source

  • 🎉 Added support for TiDB Cloud Serverless driver:

    import { connect } from '@&#8203;tidbcloud/serverless';
    import { drizzle } from 'drizzle-orm/tidb-serverless';
    
    const client = connect({ url: '...' });
    const db = drizzle(client);
    await db.select().from(...);

v0.31.1

Compare Source

New Features

Live Queries 🎉

For a full explanation about Drizzle + Expo welcome to discussions

As of v0.31.1 Drizzle ORM now has native support for Expo SQLite Live Queries!
We've implemented a native useLiveQuery React Hook which observes necessary database changes and automatically re-runs database queries. It works with both SQL-like and Drizzle Queries:

import { useLiveQuery, drizzle } from 'drizzle-orm/expo-sqlite';
import { openDatabaseSync } from 'expo-sqlite/next';
import { users } from './schema';
import { Text } from 'react-native';

const expo = openDatabaseSync('db.db', { enableChangeListener: true });

</details>

---

### Configuration

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

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

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

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/zws-im/zws).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4yNjkuMiIsInVwZGF0ZWRJblZlciI6IjM5LjE5LjAiLCJ0YXJnZXRCcmFuY2giOiJtYWluIn0=-->

@renovate renovate bot added the dependencies Pull requests that update a dependency file label Mar 30, 2024
Copy link
Contributor Author

renovate bot commented Mar 30, 2024

Branch automerge failure

This PR was configured for branch automerge. However, this is not possible, so it has been raised as a PR instead.


  • Branch has one or more failed status checks

Copy link

vercel bot commented Mar 30, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
zws ⬜️ Ignored (Inspect) Visit Preview Nov 26, 2024 6:48am

@renovate renovate bot force-pushed the renovate/drizzle-orm-0.x branch 4 times, most recently from c7b8eeb to f291111 Compare April 2, 2024 02:01
@renovate renovate bot changed the title build(deps): update dependency drizzle-orm to v0.30.6 build(deps): update dependency drizzle-orm to v0.30.7 Apr 3, 2024
@renovate renovate bot force-pushed the renovate/drizzle-orm-0.x branch 10 times, most recently from 8127784 to 4e5e16b Compare April 9, 2024 10:58
@renovate renovate bot force-pushed the renovate/drizzle-orm-0.x branch 2 times, most recently from e07dcc9 to 9d8a962 Compare April 11, 2024 10:05
@renovate renovate bot changed the title build(deps): update dependency drizzle-orm to v0.30.7 build(deps): update dependency drizzle-orm to v0.30.8 Apr 11, 2024
@renovate renovate bot force-pushed the renovate/drizzle-orm-0.x branch 3 times, most recently from b114a1c to 007de52 Compare April 15, 2024 23:13
@renovate renovate bot force-pushed the renovate/drizzle-orm-0.x branch 3 times, most recently from 7ea8731 to 8fde36f Compare April 21, 2024 15:35
@renovate renovate bot changed the title build(deps): update dependency drizzle-orm to v0.30.8 build(deps): update dependency drizzle-orm to v0.30.9 Apr 21, 2024
@renovate renovate bot force-pushed the renovate/drizzle-orm-0.x branch 2 times, most recently from d517e8d to a785e83 Compare April 24, 2024 03:33
@renovate renovate bot force-pushed the renovate/drizzle-orm-0.x branch 2 times, most recently from f61579a to b4decb5 Compare October 18, 2024 13:07
@renovate renovate bot changed the title build(deps): update dependency drizzle-orm to v0.35.1 build(deps): update dependency drizzle-orm to v0.35.2 Oct 18, 2024
@renovate renovate bot changed the title build(deps): update dependency drizzle-orm to v0.35.2 build(deps): update dependency drizzle-orm to v0.35.3 Oct 21, 2024
@renovate renovate bot changed the title build(deps): update dependency drizzle-orm to v0.35.3 build(deps): update dependency drizzle-orm to v0.36.0 Oct 30, 2024
Copy link

vercel bot commented Oct 30, 2024

Deployment failed with the following error:

Resource is limited - try again in 17 minutes (more than 100, code: "api-deployments-free-per-day").

@renovate renovate bot force-pushed the renovate/drizzle-orm-0.x branch 2 times, most recently from 076c681 to 33e3dbd Compare November 6, 2024 19:03
Copy link

vercel bot commented Nov 6, 2024

Deployment failed with the following error:

Resource is limited - try again in 41 minutes (more than 100, code: "api-deployments-free-per-day").

Copy link

vercel bot commented Nov 6, 2024

Deployment failed with the following error:

Resource is limited - try again in 59 minutes (more than 100, code: "api-deployments-free-per-day").

@renovate renovate bot changed the title build(deps): update dependency drizzle-orm to v0.36.0 build(deps): update dependency drizzle-orm to v0.36.1 Nov 6, 2024
@renovate renovate bot changed the title build(deps): update dependency drizzle-orm to v0.36.1 build(deps): update dependency drizzle-orm to v0.36.2 Nov 14, 2024
Copy link

vercel bot commented Nov 14, 2024

Deployment failed with the following error:

Resource is limited - try again in 25 minutes (more than 100, code: "api-deployments-free-per-day").

@renovate renovate bot changed the title build(deps): update dependency drizzle-orm to v0.36.2 build(deps): update dependency drizzle-orm to v0.36.3 Nov 15, 2024
@renovate renovate bot force-pushed the renovate/drizzle-orm-0.x branch 3 times, most recently from be08292 to c55e8c3 Compare November 22, 2024 12:11
@renovate renovate bot changed the title build(deps): update dependency drizzle-orm to v0.36.3 build(deps): update dependency drizzle-orm to v0.36.4 Nov 22, 2024
@renovate renovate bot force-pushed the renovate/drizzle-orm-0.x branch 2 times, most recently from 8a7a896 to 33b7258 Compare November 26, 2024 06:46
Copy link

vercel bot commented Nov 26, 2024

Deployment failed with the following error:

Resource is limited - try again in 19 minutes (more than 100, code: "api-deployments-free-per-day").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies Pull requests that update a dependency file
Development

Successfully merging this pull request may close these issues.

0 participants