Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cascading Deletes - Implementation Strategy for SQL connector #48

Closed
mavilein opened this issue Sep 20, 2019 · 3 comments
Closed

Cascading Deletes - Implementation Strategy for SQL connector #48

mavilein opened this issue Sep 20, 2019 · 3 comments
Labels
team/schema Issue for team Schema. tech/engines/introspection engine Issue in the Introspection Engine tech/engines/migration engine Issue in the Migration Engine tech/engines/query engine Issue in the Query Engine
Milestone

Comments

@mavilein
Copy link
Member

mavilein commented Sep 20, 2019

Goal: This issue describes how we plan to implement the feature of cascading deletes available in the Prisma Schema Language.

Idea: We would like to leverage SQLs ON DELETE CASCADE feature wherever possible. However it does not support all the usecases of Prismas cascading deletes. The idea is that the SQL feature is used as often as possible and shims are implemented where necessary in the query engine. The parts that need to be shimmed are indicate with a 🚨 below.

Problems:

  • Contrary to intuition a @relation(onDelete: CASCADE) on a field implies a SQL level ON DELETE CASCADE on the column of the related field. 💥
  • Prisma provides a field for both sides of a relation that can take a onDelete annotation. On the SQL level there is only one column, and therefore only the behavior for one side can be expressed on the SQL level.
  • For Many to Many relations we cannot express the behavior we want (deletion traversing through the join table) on the SQL level.

Analysis of where the SQL On Delete Cascasde works and where not

One To Many: Cascade from the Parent.

This could work purely on the SQL level and could also be introspected from the DDL.

Prisma schema:

model Parent {
  children Child[] @relation(onDelete: CASCADE)
}

model Child {
  parent Parent // this references the parent id
}

corresponding SQL:

Create Table Parent ( id Text );
Create Table Child ( id Text, 
                                  parent text REFERENCES Parent(id) ON DELETE CASCADE );

Semantics:

  • delete parent: children get deleted ✅
  • delete child: parent remains ✅

One To Many: Cascade from the Child.

This cannot be expressed on the SQL level and would need to be handled by Prisma. We could also not introspect this case.

Prisma schema:

model Parent {
  children Child[] 
}

model Child {
  parent Parent @relation(onDelete: CASCADE) // this references the parent id
}

corresponding SQL:

Create Table Parent ( id Text );
Create Table Child ( id Text, 
                                  parent text REFERENCES Parent(id));

Semantics:

  • delete parent: children remain ✅
  • delete child: parent gets deleted 🚨

One To Many: Cascade from both Sides

This cannot be fully expressed on the SQL level. We would need a mix of Prisma level and SQL level handling. We could therefore also not introspect this case.

Prisma schema:

model Parent {
  children Child[] @relation(onDelete: CASCADE)
}

model Child {
  parent Parent @relation(onDelete: CASCADE) // this references the parent id
}

corresponding SQL:

Create Table Parent ( id Text );
Create Table Child ( id Text, 
                                  parent text REFERENCES Parent(id)ON DELETE CASCADE);

Semantics:

  • delete parent: children remain ✅
  • delete child: parent gets deleted 🚨

Many to Many

Here the SQL level ON DELETE CASCADE statements merely ensure that there are no dangling relation entries after one of the connecting nodes are deleted. They have no connection to the Prisma level semantics. The Prisma level ones cannot be expressed in the db and therefore can also not be introspected. Here for all cases (CASCADE on child, CASCADE on parent, CASCADE on both) the implementation needs to happen on the Prisma level.

Prisma schema:

model Parent {
  children Child[] @relation(onDelete: CASCADE)
}

model Child {
  parents Parent[]
}

corresponding SQL:

Create Table Parent ( id Text );
Create Table Child ( id Text );
Create Table _ParentToChild (
  parent Text REFERENCES Parent(id) ON DELETE CASCADE,
  child Text REFERENCES Child(id) ON DELETE CASCADE
);

Semantics:

  • delete parent: children get deleted 🚨
  • delete child: parents remain ✅
@yoshuawuyts
Copy link
Contributor

Note from triage: this is still intended to be addressed. This will come up once we do more work on migrate.

@yoshuawuyts yoshuawuyts added tech/engines/introspection engine Issue in the Introspection Engine tech/engines/migration engine Issue in the Migration Engine tech/engines/query engine Issue in the Query Engine labels Jul 28, 2020
@yoshuawuyts
Copy link
Contributor

Triage: no change

@albertoperdomo albertoperdomo added the team/schema Issue for team Schema. label Nov 25, 2020
@pimeys
Copy link
Contributor

pimeys commented Jul 6, 2021

Fixed in this issue prisma/prisma#2810

@pimeys pimeys closed this as completed Jul 6, 2021
@pimeys pimeys added this to the 2.26.0 milestone Jul 6, 2021
miguelff pushed a commit that referenced this issue Apr 20, 2023
Flip postgres SSL certificate verification default
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team/schema Issue for team Schema. tech/engines/introspection engine Issue in the Introspection Engine tech/engines/migration engine Issue in the Migration Engine tech/engines/query engine Issue in the Query Engine
Projects
None yet
Development

No branches or pull requests

4 participants