Reputation: 93
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?
Upvotes: 7
Views: 6107
Reputation: 1672
In case anyone wants a reference from the official docs, here it is:
https://orm.drizzle.team/docs/indexes-constraints#foreign-key
If you want to do a self reference, due to a TypeScript limitations you will have to either explicitly set return type for reference callback or use a standalone foreignKey operator.
import { serial, text, integer, foreignKey, pgTable, AnyPgColumn } from "drizzle-orm/pg-core";
export const user = pgTable("user", {
id: serial("id"),
name: text("name"),
parentId: integer("parent_id").references((): AnyPgColumn => user.id)
});
// or
export const user = pgTable("user", {
id: serial("id"),
name: text("name"),
parentId: integer("parent_id"),
}, (table) => [
foreignKey({
columns: [table.parentId],
foreignColumns: [table.id],
name: "custom_fk"
})
]);
Upvotes: 3
Reputation: 1452
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
Upvotes: 7
Reputation: 121
According to the [BUG]: Self reference foreign key break relational query types #1607, you can solved like this:
export const contractsTable = pgTable("contracts", {
id: serial("id").primaryKey(),
underlyingId: integer("underlying_id").references((): AnyPgColumn => contractsTable.id),
})
export const contractsRelations = relations(
contractsTable,
({ one, many }) => ({
underlying: one(contractsTable, {
fields: [contractsTable.underlyingId],
references: [contractsTable.id],
}),
})
);
Upvotes: 12