Report hasn't been filed before.
What version of drizzle-orm are you using?
1.0.0@beta.22
What version of drizzle-kit are you using?
1.0.0@beta.22
Other packages
No response
Describe the Bug
Affected Setups
- Drizzle ORM connecting to any PostgreSQL database
- I only tested it using the
node-postgres (pg) driver
What is the undesired behavior?
- The Problem: When
migrations.schema inside drizzle.config.ts matches the postgres db username, drizzle-kit migrate creates all user defined tables on the "$user" schema, instead of the expected "public" schema. (EDITED)
- This does NOT happen, when
migrations.schema is set to something other than the db username "$user".
- Side Effect: The
schema field inside snapshot.json still points to "public", even though the tables were actually created on the "drizzle" schema.
What are the steps to reproduce it?
- Setup a postgres Database with the owner
drizzle
- Set
migrations.schema in drizzle.config.ts to the same value as the db username that owns the db ("drizzle"):
import { config } from "dotenv";
import { defineConfig } from "drizzle-kit";
config({ path: ".env" });
export default defineConfig({
schema: "./src/db/schema.ts",
out: "./src/db/migrations",
dialect: "postgresql",
dbCredentials: { url: process.env.DATABASE_URL! },
migrations: { schema: "drizzle" }, // Or just set it to what the db username is, they just have to be exactly the same
});
- Define a standard table in
schema.ts without using pgSchema:
import { pgTable as table, text } from "drizzle-orm/pg-core";
export const user = table("user", {
id: text("id").primaryKey(),
name: text("name").notNull(),
email: text("email").notNull().unique(),
});
- Run
drizzle-kit generate. Notice how the generated sql is correct: It's "user", and NOT "drizzle"."user"
Generated SQL src/db/migrations/[timestamp]/migration.sql:
CREATE TABLE "user" (
"id" text PRIMARY KEY,
"name" text NOT NULL,
"email" text NOT NULL UNIQUE,
);
Snapshot src/db/migrations/[timestamp]/snapshot.json:
- Now run
drizzle-kit migrate.
- Check the database relations using
\d in psql. The user table will be defined on the drizzle schema, entirely contradicting the snapshot.json which defines it under public.
DATABASE REALITY:
List of relations
Schema | Name | Type | Owner
---------+-----------------------------+----------+---------
drizzle | __drizzle_migrations | table | drizzle
drizzle | __drizzle_migrations_id_seq | sequence | drizzle
drizzle | user | table | drizzle
^
INCORRECT
- Optional: To prove that this only happens when
migrations.schema is set to "drizzle", execute DROP DATABASE example; and start again at step 1. But now set migrations.schema to something other than the db username or "public" and observe how the issue goes away. BEWARE: If you do not drop the database, the bug persists. Meaning, if you simply drop all the tables or the "drizzle" schema, and then re-run the migrations using drizzle-kit migrate, then migrations.schema will keep controlling the schema of all user defined tables.
What is the desired result?
DESIRED RESULT:
List of relations
Schema | Name | Type | Owner
---------+-----------------------------+----------+---------
drizzle | __drizzle_migrations | table | drizzle
drizzle | __drizzle_migrations_id_seq | sequence | drizzle
public | user | table | drizzle
^
CORRECT
-
The migrations.schema configuration property should only ever dictate the schema for Drizzle's internal migration tables and sequences, namely: the __drizzle_migrations table and the __drizzle_migrations_id_seq sequence
-
Application tables defined without an explicit pgSchema layout should ALWAYS respect the database driver's native environment or fallback to public, instead of the schema specified in config.migrations.schema.
-
The generated snapshot.json should always be in sync with what gets actually created in the database (only the schema property is wrong in this case).
Workarounds
Workaround 1
Add the following code to the top of the generated migration.sql file:
CREATE SCHEMA IF NOT EXISTS public;
SET search_path TO public;
Workaround 2
(if you don't want to manually edit migration.sql files)
Set config.migrations.schema to something other than "drizzle" (e.g. "public"), to create all tables on the public schema, and thus remove the schema mismatch between the database reality and the snapshot.json file.
Related issues
Report hasn't been filed before.
What version of
drizzle-ormare you using?1.0.0@beta.22
What version of
drizzle-kitare you using?1.0.0@beta.22
Other packages
No response
Describe the Bug
Affected Setups
node-postgres(pg) driverWhat is the undesired behavior?
migrations.schemainsidedrizzle.config.tsmatches the postgres db username,drizzle-kit migratecreates all user defined tables on the"$user"schema, instead of the expected"public"schema. (EDITED)migrations.schemais set to something other than the db username"$user".schemafield insidesnapshot.jsonstill points to"public", even though the tables were actually created on the"drizzle"schema.What are the steps to reproduce it?
drizzlemigrations.schemaindrizzle.config.tsto the same value as the db username that owns the db ("drizzle"):schema.tswithout usingpgSchema:drizzle-kit generate. Notice how the generated sql is correct: It's"user", and NOT"drizzle"."user"Generated SQL
src/db/migrations/[timestamp]/migration.sql:Snapshot
src/db/migrations/[timestamp]/snapshot.json:{ "version": "8", "dialect": "postgres", "id": "a03e228c-9e0f-4469-adfe-9692249ef1f9", "prevIds": [ "00000000-0000-0000-0000-000000000000" ], "ddl": [ { "isRlsEnabled": false, "name": "user", "entityType": "tables", "schema": "public", // <- notice EXPECTED schema }, { "type": "text", /* [...] */ "name": "id", "entityType": "columns", "schema": "public", // <- notice EXPECTED schema "table": "user" }, { "type": "text", /* [...] */ "name": "name", "entityType": "columns", "schema": "public", // <- notice EXPECTED schema "table": "user" }, { "type": "text", /* [...] */ "name": "email", "entityType": "columns", "schema": "public", // <- notice EXPECTED schema "table": "user" } /* [... ETC ...] */ ], "renames": [] }drizzle-kit migrate.\dinpsql. Theusertable will be defined on thedrizzleschema, entirely contradicting thesnapshot.jsonwhich defines it underpublic.DATABASE REALITY:
migrations.schemais set to"drizzle", executeDROP DATABASE example;and start again at step 1. But now setmigrations.schemato something other than the db username or"public"and observe how the issue goes away. BEWARE: If you do not drop the database, the bug persists. Meaning, if you simply drop all the tables or the"drizzle"schema, and then re-run the migrations usingdrizzle-kit migrate, thenmigrations.schemawill keep controlling the schema of all user defined tables.What is the desired result?
DESIRED RESULT:
The
migrations.schemaconfiguration property should only ever dictate the schema for Drizzle's internal migration tables and sequences, namely: the__drizzle_migrationstable and the__drizzle_migrations_id_seqsequenceApplication tables defined without an explicit
pgSchemalayout should ALWAYS respect the database driver's native environment or fallback topublic, instead of the schema specified inconfig.migrations.schema.The generated
snapshot.jsonshould always be in sync with what gets actually created in the database (only theschemaproperty is wrong in this case).Workarounds
Workaround 1
Add the following code to the top of the generated
migration.sqlfile:Workaround 2
(if you don't want to manually edit
migration.sqlfiles)Set
config.migrations.schemato something other than"drizzle"(e.g."public"), to create all tables on the public schema, and thus remove the schema mismatch between the database reality and thesnapshot.jsonfile.Related issues