Custom Types aren't inheriting the schema name but is undefined

I have a working table that is currently being created as my_schema.user but when I try to add a custom type (bytea) then that particular column is setting the schema value to undefined.
query: 'ALTER TABLE "my_schema"."user" ALTER COLUMN "image" SET DATA TYPE "undefined"."bytea";',
params: [],
cause: error: schema "undefined" does not exist
query: 'ALTER TABLE "my_schema"."user" ALTER COLUMN "image" SET DATA TYPE "undefined"."bytea";',
params: [],
cause: error: schema "undefined" does not exist
In my ~db/my-schema.ts I have an export.
import { pgSchema } from "drizzle-orm/pg-core";

export const mySchema = pgSchema("my_schema");
import { pgSchema } from "drizzle-orm/pg-core";

export const mySchema = pgSchema("my_schema");
This is my user.ts file.
import {
boolean,
customType,
index,
text,
timestamp,
} from "drizzle-orm/pg-core";
import { mySchema } from "~/db/my-schema.js";
import { timestamps } from "~/db/schema/columns.helpers.js";

// Custom Types
const bytea = customType<{
data: string;
driverData: Buffer;
default: false;
}>({
dataType() {
return "bytea";
},
toDriver(hash: string): Buffer {
return Buffer.from(hash, "hex");
},
fromDriver(hashBuffer: Buffer): string {
return hashBuffer.toString("hex");
},
});

// Enums
export const members = mySchema.enum("members", ["member", "admin"]);

// Tables
export const user = mySchema.table(
"user",
{
id: text().primaryKey(),
name: text().notNull(),
country: text(),
username: text(),
displayUsername: text(),
email: text().notNull().unique(),
emailVerified: boolean().default(false).notNull(),
image: bytea(),
role: members().default("member").notNull(),
banned: boolean().default(false),
banReason: text(),
banExpires: timestamp({ withTimezone: true }),
metadata: text(),
...timestamps,
},
(table) => [index("user_email_idx").on(table.email)],
);
import {
boolean,
customType,
index,
text,
timestamp,
} from "drizzle-orm/pg-core";
import { mySchema } from "~/db/my-schema.js";
import { timestamps } from "~/db/schema/columns.helpers.js";

// Custom Types
const bytea = customType<{
data: string;
driverData: Buffer;
default: false;
}>({
dataType() {
return "bytea";
},
toDriver(hash: string): Buffer {
return Buffer.from(hash, "hex");
},
fromDriver(hashBuffer: Buffer): string {
return hashBuffer.toString("hex");
},
});

// Enums
export const members = mySchema.enum("members", ["member", "admin"]);

// Tables
export const user = mySchema.table(
"user",
{
id: text().primaryKey(),
name: text().notNull(),
country: text(),
username: text(),
displayUsername: text(),
email: text().notNull().unique(),
emailVerified: boolean().default(false).notNull(),
image: bytea(),
role: members().default("member").notNull(),
banned: boolean().default(false),
banReason: text(),
banExpires: timestamp({ withTimezone: true }),
metadata: text(),
...timestamps,
},
(table) => [index("user_email_idx").on(table.email)],
);
Do custom types inherit a custom schema name?
3 Replies
A-J Roos
A-J RoosOP4w ago
The solution was to wipe all migrations and the database and to recreate everything. Now the bytea is being created as part of the initial table.
CREATE TABLE "my_schema"."user" (
"id" text PRIMARY KEY NOT NULL,
"name" text NOT NULL,
"country" text,
"username" text,
"display_username" text,
"email" text NOT NULL,
"email_verified" boolean DEFAULT false NOT NULL,
"image" "bytea",
"role" "my_schema"."members" DEFAULT 'member' NOT NULL,
"banned" boolean DEFAULT false,
"ban_reason" text,
"ban_expires" timestamp with time zone,
"metadata" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "user_email_unique" UNIQUE("email")
);
CREATE TABLE "my_schema"."user" (
"id" text PRIMARY KEY NOT NULL,
"name" text NOT NULL,
"country" text,
"username" text,
"display_username" text,
"email" text NOT NULL,
"email_verified" boolean DEFAULT false NOT NULL,
"image" "bytea",
"role" "my_schema"."members" DEFAULT 'member' NOT NULL,
"banned" boolean DEFAULT false,
"ban_reason" text,
"ban_expires" timestamp with time zone,
"metadata" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "user_email_unique" UNIQUE("email")
);
JustWayne
JustWayne4w ago
If you don't declare the name of the field in the data-type like this my_col: text("my_col") and if you share those declarations between tables, it can cause problems. For instance, if I do this: const shared_fields = { x: integer(), y: integer(), z: integer() }; and then const tbl = mySchema.table("tbl", { id: integer(), ...shared_fields }); I say this because I saw you spreading ...timestamps fields. I stopped sharing same-instances of shared fields for the reason that, when I inspected my own shared_fields thing, I noticed that the object gets modified for each table that you attach it to (to add the name of the field which had been omitted from x, y and z.) and that's not something you really want. Instead, what I do now is to spread the result of a function that returns the shared fields so, e.g. ...shared.fields() where the fields() function returns a new instance of {x: integer(), y: integer(), z: integer() } every time. Not sure if that caused your problem, but I believe it's possible
YK_DZ
YK_DZ3w ago
I found that when adding a new bytea column the migration SQL generated by Drizzle is correct, but altering an existing column's data type to bytea produces this error. Due to this inconsistency, I believe this is a bug on customType in drizzle-kit.

Did you find this page helpful?