Convert SQL One-to-One Foreign Keys to Prisma Relations
Learn how SQL UNIQUE foreign key constraints convert to Prisma one-to-one relation fields. Covers optional and required one-to-one relations with @relation.
Detailed Explanation
One-to-One Relations
A one-to-one relationship in SQL is a foreign key with a UNIQUE constraint, ensuring each parent has at most one related child. Prisma models this with singular relation fields on both sides.
Example SQL
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL
);
CREATE TABLE profiles (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL UNIQUE,
bio TEXT,
avatar_url VARCHAR(2048),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
Generated Prisma Schema
model User {
id Int @id @default(autoincrement())
name String
profile Profile?
@@map("users")
}
model Profile {
id Int @id @default(autoincrement())
userId Int @unique @map("user_id")
bio String? @db.Text
avatarUrl String? @db.VarChar(2048) @map("avatar_url")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map("profiles")
}
How It Works
- The foreign key column
user_idhas aUNIQUEconstraint — this signals a 1:1 relationship. - In Prisma, the child model (
Profile) holds the@relationwithfieldsandreferences. - The parent model (
User) has an optional back-referenceProfile?(optional because the profile may not exist yet). - The
@uniqueattribute onuserIdin Prisma enforces the one-to-one constraint.
Required vs Optional
// Optional: user may or may not have a profile
model User {
profile Profile?
}
// Required: every user must have a profile
model User {
profile Profile
}
Whether the relation is optional on the parent side depends on your business logic. The SQL schema alone cannot express this — a NOT NULL FK on the child side means "every profile must have a user" but does not mean "every user must have a profile."
Compared to Embedding
An alternative to a separate 1:1 table is to put all fields in the parent table:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
bio TEXT,
avatar_url VARCHAR(2048)
);
Use a separate table when:
- The related data is large and rarely accessed
- You want independent permission control
- The related data has its own lifecycle (e.g., separate created_at/updated_at)
The converter generates a 1:1 relation whenever it detects a UNIQUE foreign key, and adds the bidirectional relation fields automatically.
Self-Referential One-to-One
A less common pattern is self-referential 1:1:
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
mentor_id INTEGER UNIQUE,
FOREIGN KEY (mentor_id) REFERENCES employees(id)
);
model Employee {
id Int @id @default(autoincrement())
name String
mentorId Int? @unique @map("mentor_id")
mentor Employee? @relation("EmployeeMentor", fields: [mentorId], references: [id])
mentee Employee? @relation("EmployeeMentor")
@@map("employees")
}
Use Case
You have a users table with a separate profiles table linked by a UNIQUE foreign key. The converter generates Prisma one-to-one relation fields on both models with the correct @unique constraint and cascade behavior.
Try It — SQL to Prisma Schema
Related Topics
Convert SQL Foreign Keys to Prisma One-to-Many Relations
Relations
Convert SQL Junction Tables to Prisma Many-to-Many Relations
Relations
Convert a Simple SQL Table to a Prisma Model
Basic Models
Convert SQL UNIQUE Constraints to Prisma @unique and @@unique
Advanced Features
Convert a SQL User Authentication Schema to Prisma
Real-World Schemas