postgresqlbyteadrizzle

How to represent 'bytea' datatype from pg inside new drizzle orm?


Im trying to learn new drizzle orm for node js, and im here trying to create a small auth database to see how the orm works.

using 'pnpm drizzle-kit generate:pg' i generated a schema from a pg database, but bytea datatype was not parsed to ts. as the drizzle is new a orm, the doc dosen't have solution for my problem. i needed a way to represent bytea pg datatype inside drizzle orm.

here is the schema code generated by drizzle kit.

export const user = pgTable(
  "user",
  {
    id: uuid("id").primaryKey().notNull(),
    firstname: varchar("firstname", { length: 35 }).notNull(),
    middlename: varchar("middlename", { length: 35 }),
    lastname: varchar("lastname", { length: 35 }).notNull(),
    // TODO: failed to parse database type 'bytea'
    passphrase: unknown("passphrase").notNull(),
    // TODO: failed to parse database type 'bytea'
    salt: unknown("salt").notNull(),
    email: varchar("email", { length: 50 }).notNull(),
  },
  (table) => {
    return {
      email: uniqueIndex("user_email").on(table.email),
    };
  }
);


Solution

  • You can use custom types. Here is the implementation of the bytea custom type:

    const bytea = customType<{ data: Buffer; notNull: false; default: false }>({
      dataType() {
        return "bytea";
      },
    });
    

    You can use toDriver and fromDriver functions to map the app data to db type, and db type to app data. For instance if you want to store bytea in db, but want to retrieve it as hex string in your application, you can go like this:

    const bytea = customType<{ data: string; notNull: false; default: false }>({
      dataType() {
        return "bytea";
      },
      toDriver(val) {
        let newVal = val;
        if (val.startsWith("0x")) {
          newVal = val.slice(2);
        }
    
        return Buffer.from(newVal, "hex");
      },
      fromDriver(val) {
        return val.toString("hex");
      },
    });