Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Drizzle ORM · Function

foreignKey

foreignKey declares a database-level foreign-key constraint in a Drizzle table definition. It maps one or more child-table columns to corresponding columns in a referenced parent table, with optional naming and referential actions.

How it works

The foreignKey operator declares a database constraint by pairing local columns with referenced columns. It is especially useful for multi-column relationships and can be given a name plus delete and update actions through chained methods.

Syntax

foreignKey({ name?, columns, foreignColumns }).onDelete(action?).onUpdate(action?)

Parameters

NameTypeDescription
namestringOptional constraint name.
columnsColumn[]Columns in the child table.
foreignColumnsColumn[]Referenced columns in the parent table.

Returns

A foreign-key constraint definition for inclusion in a table declaration.

Key points

  • Drizzle supports foreign-key declarations both in column definitions and through the dedicated table-level operator.
  • columns contains the local table columns participating in the constraint.
  • foreignColumns identifies the referenced columns in the parent table.
  • A custom constraint name can be supplied with the name property.
  • Referential actions for operator-defined constraints are configured using the documented chained action methods.

Common mistakes

  • Use the dedicated operator when the relationship spans multiple columns rather than relying only on a column-level reference.
  • This is enforced by the database during write operations; it is not merely an application-level relationship description.
  • Do not confuse foreignKey constraints with Drizzle relations; the latter do not create database constraints implicitly.

Example: Define a foreign key

import { integer, pgTable, serial, text, foreignKey } from "drizzle-orm/pg-core";

export const users = pgTable("users", {
  id: serial("id").primaryKey(),
  name: text("name"),
});

export const posts = pgTable("posts", {
  id: serial("id").primaryKey(),
  authorId: integer("author_id").notNull(),
}, (table) => [
  foreignKey({
    name: "posts_author_fk",
    columns: [table.authorId],
    foreignColumns: [users.id],
  }),
]);

Defines a PostgreSQL foreign-key constraint from posts.authorId to users.id.

When to use it

Composite foreign keys

A relationship uses two or more columns on each side.

Named constraints

A constraint needs a predictable name for migrations or database inspection.

Referential actions

Parent-row changes must propagate or be restricted explicitly.

Database integrity

Schema relationships must be enforced independently of application queries.

Interview questions

QWhat does Drizzle's foreignKey operator do?

foreignKey creates a database-level foreign-key constraint. Its configuration identifies local columns and the referenced foreignColumns, and it can optionally assign a constraint name.

Follow-up: How would you model a composite relationship? Supply multiple corresponding columns in columns and foreignColumns, preserving their positional pairing.

QWhen should you use foreignKey instead of a column reference?

The operator is declared in the table callback and returns a constraint definition. It is useful when a foreign key involves more than one column.

Follow-up: How can referential actions be configured? Chain .onDelete(...) and .onUpdate(...) on the foreign-key definition.

QHow do foreign keys differ from Drizzle relations?

A foreign key is enforced at the database level on inserts, updates, and deletes, while relations are application-level abstractions. They can be used together but neither depends on the other.

Follow-up: Can relations alone create foreign keys? No; the documentation states that relations do not affect the database schema or implicitly create foreign keys.

  • references()
  • relations
  • onDelete()
  • onUpdate()
  • primaryKey
  • unique

Source: Indexes & Constraints - Drizzle ORM. Checked 2026-10-16.