typescriptpostgresqlormnode-postgresdrizzle

How to declare self-referencing foreign key with Drizzle ORM


In a Typescript project, declaring a table using Drizzle on postgres-node as follows:


const contractsTable = pgTable("contracts", {
    id: serial("id").primaryKey(),
    underlyingId: integer("underlying_id").references(() => contractsTable.id),
    //...
})

results in the following Typescript error:

'contractsTable' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

Maintaining a separate type would be impractical because the schema is massive and is subject to change.

Is there a way to get Typescript to infer the correct type? I failed to do this through aliasing or casting the PgIntegerBuilderInitial type.

We also define a relationship as follows:

const contractsRelations = relations(
    contractsTable,
    ({ one, many }) => ({
        underlying: one(contractsTable, {
            fields: [contractsTable.underlyingId],
            references: [contractsTable.id],
        }),
        //...
    })
);

but I do need the database level constraint. Any ideas?


Solution

  • You can create a self reference in the table being created by doing

    export const contractsTable = pgTable(
      "contracts",
      {
        id: serial("id").primaryKey(),
        underlyingId: integer("underlying_id"),
      },
      (table) => {
        return {
          parentReference: foreignKey({
            columns: [table.underlyingId],
            foreignColumns: [table.id],
            name: "contracts_underlying_id_fkey",
          }),
        };
      }
    );
    

    Correctly generated the foreign key.

    Taken from Discord conversations and tested on

       drizzle-kit 0.21.4
       drizzle-orm 0.30.10