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

Shorter many to many relation names #6917

Merged
merged 14 commits into from
Nov 22, 2021
Merged

Conversation

emmatown
Copy link
Member

Closes #6812

This makes two-sided many to many relationships only include one of the sides in the relation table (which Prisma will then include in the table name with an _ in front). I've also removed _many from the end of one-sided many relationships for consistency.

@changeset-bot

This comment was marked as resolved.

@vercel
Copy link

vercel bot commented Nov 11, 2021

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/keystonejs/keystone-next-docs/DoBsBFAC3cLzTVEizRryvG1baDRY
✅ Preview: https://keystone-next-docs-git-shorter-many-to-many-r-886fc3-keystonejs.vercel.app

@codesandbox-ci
Copy link

codesandbox-ci bot commented Nov 11, 2021

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

@emmatown emmatown requested a review from a team November 11, 2021 01:56
@vercel vercel bot temporarily deployed to Preview November 11, 2021 23:05 Inactive
@dcousens
Copy link
Member

Rebased

@dcousens dcousens force-pushed the shorter-many-to-many-relation-names branch from 4cc0307 to 49bcd6d Compare November 15, 2021 00:32
@vercel vercel bot temporarily deployed to Preview November 15, 2021 00:32 Inactive
@vercel vercel bot temporarily deployed to Preview November 17, 2021 02:06 Inactive
@vercel vercel bot temporarily deployed to Preview November 17, 2021 02:46 Inactive
@dcousens dcousens force-pushed the shorter-many-to-many-relation-names branch from 1782294 to 77a39e9 Compare November 17, 2021 03:39
@vercel vercel bot temporarily deployed to Preview November 17, 2021 03:39 Inactive
@vercel vercel bot temporarily deployed to Preview November 17, 2021 03:59 Inactive
@dcousens
Copy link
Member

dcousens commented Nov 17, 2021

I think we have a few paths with this:

  • Recommending a migration strategy in the release notes ✅
  • Adding a temporary option to opt-in to the previous behaviour of config.experimental.useLegacyRelationNames, or
  • Adding a temporary option to opt-in to the new behaviour of config.experimental.useShortRelationNames

The useShortRelationNames option could help a user who does a blind update, as it removes any automated migration in the default case. The automatic DROP TABLE if we opt for useLegacyRelationNames is worrying if users aren't being careful and reading the generated migration.

The downside, is we are simply kicking that can down the road.

Walking through the useMigrations: true flow with this and the useMigrations: false, I am happy with useLegacyRelationNames in that Prisma shows enough warnings that any code review and or any attempt at running this in a local development environment warns the user about a destructive action.

I am strongly against the useMigrations flag generally being opt-in instead of opt-out. I think that needs improvement.

@vercel vercel bot temporarily deployed to Preview November 17, 2021 04:20 Inactive
@dcousens dcousens force-pushed the shorter-many-to-many-relation-names branch from abb0365 to 261befd Compare November 18, 2021 04:57
@vercel vercel bot temporarily deployed to Preview November 18, 2021 04:57 Inactive
@dcousens dcousens force-pushed the shorter-many-to-many-relation-names branch from 261befd to 3f0228c Compare November 18, 2021 04:58
@vercel vercel bot temporarily deployed to Preview November 18, 2021 04:58 Inactive
@vercel vercel bot temporarily deployed to Preview November 18, 2021 04:59 Inactive
@dcousens dcousens force-pushed the shorter-many-to-many-relation-names branch from f78118b to 36ceebe Compare November 18, 2021 05:08
@vercel vercel bot temporarily deployed to Preview November 18, 2021 05:08 Inactive
@@ -252,7 +252,7 @@ We need to reset the ${credentials.type} database "${credentials.database}" at $
console.log(`✨ A migration has been created at migrations/${generatedMigrationName}`);

let shouldApplyMigration =
migrationCanBeApplied && (await confirmPrompt('Would you like to apply this migration?'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mitchellhamilton I have defaulted this to no, this should help prevent an unintentional DROP.

@vercel vercel bot temporarily deployed to Preview November 18, 2021 05:57 Inactive
@vercel vercel bot temporarily deployed to Preview November 18, 2021 06:00 Inactive
@dcousens dcousens force-pushed the shorter-many-to-many-relation-names branch from 1fa49fe to 1c9d998 Compare November 18, 2021 06:02
@vercel vercel bot temporarily deployed to Preview November 18, 2021 06:06 Inactive
@dcousens dcousens requested a review from molomby November 18, 2021 06:07
@vercel vercel bot temporarily deployed to Preview November 18, 2021 06:09 Inactive
@molomby

This comment has been minimized.

@molomby
Copy link
Member

molomby commented Nov 19, 2021

If you were building the DB yourself, most people would name these adjacency tables for the two tables they related. Eg, given User.reviewedPosts <-> Post.reviewedByUsers you'd name the table users_posts, User_Post or something like that. Obviously the problem with this generally is when you have multiple many-to-many relationships, like, say you also have User.contributedToPosts <-> Post.contributors. In that case (again, assuming you were doing this "by hand") you'd just pick sensible names for the tables, eg: maybe PostReviews for the former and PostContributions for the latter. Problem solved.

Having multiple many-to-many relationships between two lists is going to be pretty rare for most systems but of course, we still need to solve for it in the general case. My "perfect world" solution would look something like this:

  • By default, adjacency tables are named for ${LEFT_LIST}_${RIGHT_LIST}, as above
  • We add a config option to relationship fields that lets app builders specify a alternate "relationship key" if they want
  • If you have multiple many-to-many relationships between two lists with no relationship keys Keystone throws an error on startup, directing devs to specify a value for one of the colliding relationships
  • I suppose we'd also need to validate the dev hasn't set conflicting keys/names on both sides of the same relationship, etc.

This is more work that some other solutions we could use but the upsides are..

  • It follows our general principal that the automatically generated stuff should, ideally, be "what you'd build yourself if you had time"
  • It give us another option for people when upgrading to this release, eg. "if you don't want your DB structure to change, update the config for all your existing many-to-many relationships and specify a relationship key matching your the current table names" (It might be worth it just for this, no?)
  • Letting app builders specify a "relationship key"/table name to use will sometimes be handy even if there's no naming conflict. Eg. to align with an existing DB structure or, really, by anyone who care about the details of their DB structure

@dcousens
Copy link
Member

dcousens commented Nov 21, 2021

I think users_reviewed_posts (approximately what this implements) neatly accounts for the multiple many-to-many scenario without issue and meets the canonical expectation.

The problem is we have users_reviewedPosts_posts_reviewedByUsers now, and that's triggering PostgreSQL inbuilt limits quickly.

The primary concern for me is that by automatically generating migrations [with this change], without enforcing user consideration, could be an unnecessary foot gun. Maybe I'm too conservative.

@molomby
Copy link
Member

molomby commented Nov 22, 2021

I think users_reviewed_posts (approximately what this implements) neatly accounts for the multiple many-to-many scenario without issue and meets the canonical expectation.

Yeah the current solution is fine – I like that it prevents collisions but I don't love the way it arbitrarily picks the name (ie. depending on which list is left and which is right). Like, for User.reviewedPosts <-> Post.reviewedByUsers my table's either going to be User_reviewedPosts or Post_reviewedByUsers, both of which are ok but, as a developer, I don't know which I'm going to get.

Also, if you're going to give people a way to effect the name of these tables (ie. useLegacyManyRelationNames) why not just let them pick it? Eg. instead of...

const relationName = `${leftRel.listKey}_${leftRel.fieldPath}${
    useLegacyManyRelationNames ? `_${rightRel.listKey}_${rightRel.fieldPath}` : ''
}`;

Why not...

const relationName = (leftRel.name || rightRel.name) || `${leftRel.listKey}_${rightRel.listKey}`;

The primary concern for me is that by automatically generating migrations [with this change], without enforcing user consideration, could be an unnecessary foot gun. Maybe I'm too conservative.

Yeah, this is the more important problem really, I just don't have any helpful opinion on it.

@vercel vercel bot temporarily deployed to Preview November 22, 2021 04:34 Inactive
@vercel vercel bot temporarily deployed to Preview November 22, 2021 05:19 Inactive
@vercel vercel bot temporarily deployed to Preview November 22, 2021 05:24 Inactive
Co-authored-by: Daniel Cousens <413395+dcousens@users.noreply.github.com>
@vercel vercel bot temporarily deployed to Preview November 22, 2021 05:35 Inactive
@vercel vercel bot temporarily deployed to Preview November 22, 2021 05:51 Inactive
@emmatown emmatown merged commit 04c54a4 into main Nov 22, 2021
@emmatown emmatown deleted the shorter-many-to-many-relation-names branch November 22, 2021 06:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Issues with long index names in migrations with Prisma and Postgres
3 participants