question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support (some) weak relations with no foreign key

See original GitHub issue

Problem

I need a relation in my schema so that I can query across two tables, but without the referential integrity constraints that come with a foreign key. This is related to issue #7293, but different: I am using a database that supports foreign keys (PostgreSQL) and I want them for some relations in my schema but not for others.

Suggested solution

This this discussion, @janpio showed me that I can do what I need if I just don’t run prisma migrate after adding the relation to my schema, but I want to continue to evolve my schema and use prisma migrate in the future. So, what I really need is a way to tell Prisma that a particular relation should not have a foreign key.

That could be achieved by supporting a new weak argument on a @relation attribute:

  postalCode PostalCode? @relation(fields: [code], references: [code], weak: true)

But I would be open to any other alternative.

Alternatives

Beyond not letting prisma migrate see the relation, I don’t have other ideas.

Additional context

Here are the details of my use case, which I have copied from the discussion linked above…

Briefly, it’s about using some relevant data, if available, to enrich another entity. The key thing is “if available”. It’s a weaker relationship in that you don’t know if that relevant data will be there until you look, as opposed to a definite relationship between two entities that should/can be enforced.

My schema already has regular relationships with the need for referential integrity, but now I want to add one of these weaker relationships, as well.

This is the relevant portion of my model:

model Story {
  id         String      @id @default(cuid())
  createdAt  DateTime    @default(now())
  content    String
  code       String
  postalCode PostalCode? @relation(fields: [code], references: [code])
}

model PostalCode {
  code     String   @id
  province Province
  name     String
  hotspot  Boolean
}

enum Province { ... }

The code in Story is what defines the weak relationship between stories and postal codes. Every story will always have a code, but there may or may not be an actual PostalCode entity with that code.

I’m going to be initializing the PostalCode table as part of deploying the app, loading it up with data for each postal code, including an official placename from the post office, along with information from other sources, such as whether the postal code is a hotspot. Users won’t ever change or add to this data. It will only be updated when I receive new data from the post office, process it, and load it.

When a user submits a story, they must type in the digits of their postal code. It may match one in the PostalCode table or it may not. It might not match one if it’s a newly created postal code and our data isn’t up to date yet or even just because they entered a fake postal code. That’s totally fine.

Later, when another user visits the site, we’ll retrieve the list of stories to display to them. At that point, I want to join that with the postal code data by the code that the submitter had entered. That way, I’ll be able to show the story enhanced with additional information about the postal code: the placename and an indicator if it’s a hotspot. If there is no matching PostalCode entity, no problem, I’ll just show the code the submitter typed, with no name and no hotspot indicator.

Clearly this kind of query is totally possible without having a foreign key. The only thing a foreign key would do is prevent adding the story in the first place if it doesn’t match a postal code. That’s why a foreign key won’t work in this situation.

And there’s one extra complication: we already have the Story model (without the postalCode relation) in the application, which is live and running today. Currently, we just display the postal code that the submitter typed. I want to add the PostalCode model and data so that we can show more helpful information about the stories we have and the new stories to come. With hundreds of stories and no postal codes in the database, I can’t even get as far as successfully running migrate on the schema if doing so adds the foreign key.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:11
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
hiphapiscommented, Oct 20, 2021

I need this too!!

3reactions
kyoungduckcommented, Jun 18, 2021

I need this too.

In my case, I dont use FK in my database for following reasons:

  1. FK cannot be used for partition tables.
  2. FK can lock the database, so lock contention can be occurred and query latency will be increased.
  3. Eventually, DBMS performance will be slowed down

number 2,3 is talking about performance but, 1 becomes a constraint cannot to use FK.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Weak entity without foreign key - Stack Overflow
In a relational database, a weak entity is an entity that cannot be uniquely identified by its attributes alone; therefore, it must use...
Read more >
9 reasons why there are no foreign keys constraints in your ...
The obvious problem with the lack of foreign keys is that a database can't enforce referential integrity and if it wasn't taken care...
Read more >
What do you call a relationship between two entities without a ...
It is still a foreign key, because it's a feature of your data. However, it is not enforced by a referential integrity constraint....
Read more >
QSEE Entity Relationship Models - cems.uwe.ac.uk
QSEE supports many to many relationships and these will be resolved by the ... If the whole primary key is composed of foreign...
Read more >
The Relational Model - UNC Computational Systems Biology
Relational database: a set of relations ... This is not true for any subset of the key ... Foreign key : Set of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found