When creating an implicit many to many relation, f...
# orm-help
p
When creating an implicit many to many relation, following the docs here; https://www.prisma.io/docs/concepts/components/prisma-schema/relations, the table created for the join does not have a primary called out. MySql by default requires a primary key (and for good reason, replication counts on it). Is there a way to force a primary key creation on the implicit link table?
Copy code
CREATE TABLE "Category" (
    id SERIAL PRIMARY KEY
);
CREATE TABLE "Post" (
    id SERIAL PRIMARY KEY
);
-- Relation table + indexes -------------------------------------------------------
CREATE TABLE "_CategoryToPost" (
    "A" integer NOT NULL REFERENCES "Category"(id),
    "B" integer NOT NULL REFERENCES "Post"(id)
);
CREATE UNIQUE INDEX "_CategoryToPost_AB_unique" ON "_CategoryToPost"("A" int4_ops,"B" int4_ops);
CREATE INDEX "_CategoryToPost_B_index" ON "_CategoryToPost"("B" int4_ops);
j
No there is not and we are not aware of this being a problem for MySQL in any way.
Does this depend on some server configuration?
p
When I tried creating my database on my cloud host (digitalOcean), I got the error saying a primary key is required (unless you change a db setting). From this post on SO, I gather I'll not be able to change that option though have not tried yet. The post does reference mysql docs, but again, I've not verified that. https://stackoverflow.com/questions/62418099/unable-to-create-or-change-a-table-without-a-primary-key-laravel-digitalocean
confirming DigitalOcean does require Primary Keys. From what I've ready, if you don't create one, the database creates one invisibly so maybe it would make sense to have an option to explicity create it? https://docs.digitalocean.com/products/databases/mysql/how-to/create-primary-keys/
@janpio Is there a workaround for this or should I re-tool and follow the explicit flow? (I really like the implicit one though)
j
Right now I am not aware of a workaround. You can probably create a migration file and add the primary key there manually.
But now that you mention it, this rings a bell for me. A long time ago I thought about this already...
Could you open an issue for us at the prisma/prisma repo? The info you have in here is already enough and then we can take it from here.
First step would be to confirm the workaround and document that somehow.
p
I'm very new to Prisma (and the migration stuff), but I'll give it a go. I'm currently at that phase where when things work, I'm amazed, and when they don't a launch into flounder mode until they do. Loving the potential though. I think you guys are on to something (just not sure what yet) 🙂.
prisma rainbow 2
j
Thanks so much. I think you hit an edge case there with DO's MySQL that we should cover better.
Ok, took another look at this now. Found the issue I was remembering: https://github.com/prisma/docs/issues/958
So we were aware, but decided this is a limitation people just have to deal with - which is not super cool 😕
The workaround mentioned there is indeed not to use implicit relations, which makes the API to use in your application quite a bit less nice unfortunately.
p
That does kind of suck. Just back from lunch and reading about how to make my own migration. I'm thinking I create one with the -createonly flag, modify it by hand, then run it. I did verify that in mysql I can add a primary key as composite
ALTER TABLE _NoteToTag ADD primary key (A,B)
and that seemed to work at least with no error and my app still worked. It does seem like it's something you should at least create an option for. I'm guessing the only reason it's not an error in MySql is that a long long time ago before everyone believed in primary keys, a lot of apps were built that still exist. I have a lot of road rash from having to fix those apps.
Side Note: Send my thanks to your docs team. They've done a really good job, and I for one, really appreciate it.
j
Sorry about suggesting modifying the migration - that was a red herring - if you do that all future migrations will try to remove that primary key again 😞
(Just shared your thanks in our internal #wins team with an at mention of that team 👍 )
We generally have as little options as possible, but we might just want to switch these tables to have a Primary Key at some point - maybe via that issue you could create about this 😄
(Indeed not having a PK is often worse than having one that is not used and "useless" as it is duplicated via a UNIQUE on all columns. But database design is an art...)
p
🙂. I read all about that in the docs. I assume that when you said "modify" you really meant to it the -create way, then modify. Over the years, I've done a lot of work with Microsoft's entity framework migrations so I'm aware of how fragile they can be.
Yeah, gets to a culture war thing with primary keys. I'm more of a practical dev rather then a pure one (sad to say), and though I try never to be emotionally attached to my opinions, I've gotten in a lot of battles over the years with people who think primary keys are evil and you should let the data speak for itself. Me, I like having that auto creating guid column just so I can always identify the row with absolute certainty.
👍 1
(and the guys who write databases think like me and also really like to have that guid column also)
j
Yes, I did mean
migrate dev --create-only
, then modify the file and apply it with another
migrate dev
or
migrate deploy
. The problem with that is that any future migration you create also needs to be done via
--create-only
so you can remove the statement that would undo your manual modification again 😕
(We know as soon as you break out of the "default" of Migrate usage, it becomes a lot less convenient and will hopefully soon have improvements there.)
p
hmm. sounds like maybe a better plan is to do the alter directly, then clear the migrations folder and then do
prisma introspect
? Would that somehow bring the primary key back int the initial migration file, then I can move forward with the normal migration process as I make changes?
j
It's a bit more complicated 😕
Introspection would not recognize this as an implicit relation any more and put it in there explicitly, so you would lose the nice API (and have terrible field names anyway 😛 )
The implicit relations really are not our nicest feature right now in practice. As soon as you need to change them in any way, Prisma gives up.
p
I get it. It's a hard problem. I'm putting a demo app together for a course I'm working on (React, not prisma) and I'm still wrestling with how to teach many to many relationships. I really love how easily the many to many just worked in prisma. I suppose in a production app, the corner cases (like this) would pile up. Maybe best if I revert to the standard 3 table solution that everyone expects to see.
When you said Prisma "gives up", I immediately think of the self driving car "giving up" scenario. Happened to me once on a crowded highway going around a bend. Luckily I lived to tell about it but it was a little scary. GIving up us bad.
j
We have to pick our fights 😄
On the other hand, implicit relations work perfectly in 99% of cases.
Only the "PK required" rules makes it impossible to use - which we also only encoutered with DO until now.
All other things are "missing" features like being able to add properties to the relation, sorting the relations and similar things.
(Ah, sometimes people really dislike the naming of the fields - that is also not configurable)
p
there is that. BTW, I assume you are in a far away timezone. I appreciate you spending the time answering my query.
j
One day I hope we can make any m:n relation an implicit relation with nice API support. That definitely is our vision for that part.
(Ha, I am in CET but took the afternoon off because it was to hot so am happy to finally be able to work through the things that collected while other people worked 👍 )
p
I hope you figure out the implicit relationships, but it isa path fraught with peril as it's quite far from the base table design you are mapping from. I wish the wind at your back in solving this problem but it may cause more heartache then it cures. At scale, things like locking will get really nasty.
👍 1
I found you on LinkedIN. OK to connect? (I try to collect smart people)
j
Ha, how could I say no to that after that
(...)
😛 But yep, always 👍
We are honestly surprised how little negative feedback we have gotten on the implicit relations yet. We know people use them, but they just seem to be happy with how they work.
(It is one of the oldest pieces of logic in the whole of Prisma, as it is taken over from Prisma 1 and even Graphcool)
On the other hand it is where the API is soooo much greate than the explicit jumping across tables, that makes you really appreciate what we can do if we think about this hard enough (and actually fix the bugs etc 😛 )
p
100% agree. It's ironic that I'm kind of arguing against it. I'm usually the one who, when engineers tell me why they can't do something, I'm telling them to go figure it out. I guess i've been burned so many times over the years by ORMS and leaky abstractions that it's hard to have a good attitude about it.
😆 1
j
Welcome to the club.
👍 1
Hibernate changes you.