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.

`prisma format` sets `@unique` automatically when relation is optional with MongoDB

See original GitHub issue

Bug description

Provided this pseudo schema:

datasource db {
  url      = env("DATABASE_URL")
  provider = "mongodb"
}

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["filterJson", "interactiveTransactions"]
}

model Car {
  id            String  @id @map("_id")
  activeOfferId String? @unique
  activeOffer   Offer?  @relation("ActiveOffer", references: [id], fields: [activeOfferId], onDelete: NoAction, onUpdate: NoAction)
  offers        Offer[]
}

model Offer {
  id        String @id @map("_id")
  carId     String
  car       Car    @relation(references: [id], fields: [carId], onDelete: NoAction, onUpdate: NoAction)
  activeCar Car?   @relation("ActiveOffer")
}

So a car can have many offers which can be closed. However, there could be an offer that is active, thus the ActiveOffer relationship.

The problem in here is that Prisma formatter will automatically add a @unique index on activeOfferId while it can be nullable and MongoDB won’t allow this. Is there a way not to add @unique when the relationship is optional?

How to reproduce

Create a schema file (mongodb) and add that schema I shared above. Remove the @unique and format the document (I use VSCode format).

The formatter will add @unique next to activeOfferId.

Expected behavior

No @unique gets added in an optional relationship.

Prisma information

Schema:

datasource db {
  url      = env("DATABASE_URL")
  provider = "mongodb"
}

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["filterJson", "interactiveTransactions"]
}

model Car {
  id            String  @id @map("_id")
  activeOfferId String? @unique
  activeOffer   Offer?  @relation("ActiveOffer", references: [id], fields: [activeOfferId], onDelete: NoAction, onUpdate: NoAction)
  offers        Offer[]
}

model Offer {
  id        String @id @map("_id")
  carId     String
  car       Car    @relation(references: [id], fields: [carId], onDelete: NoAction, onUpdate: NoAction)
  activeCar Car?   @relation("ActiveOffer")
}

Environment & setup

  • OS: MacOS
  • Database: MongoDB
  • Node.js version: 16

Prisma Version

prisma                  : 3.14.0
@prisma/client          : 3.14.0
Current platform        : darwin
Query Engine (Node-API) : libquery-engine 2b0c12756921c891fec4f68d9444e18c7d5d4a6a (at ../node_modules/.pnpm/@prisma+engines@3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a/node_modules/@prisma/engines/libquery_engine-darwin.dylib.node)
Migration Engine        : migration-engine-cli 2b0c12756921c891fec4f68d9444e18c7d5d4a6a (at ../node_modules/.pnpm/@prisma+engines@3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a/node_modules/@prisma/engines/migration-engine-darwin)
Introspection Engine    : introspection-core 2b0c12756921c891fec4f68d9444e18c7d5d4a6a (at ../node_modules/.pnpm/@prisma+engines@3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a/node_modules/@prisma/engines/introspection-engine-darwin)
Format Binary           : prisma-fmt 2b0c12756921c891fec4f68d9444e18c7d5d4a6a (at ../node_modules/.pnpm/@prisma+engines@3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a/node_modules/@prisma/engines/prisma-fmt-darwin)
Default Engines Hash    : 2b0c12756921c891fec4f68d9444e18c7d5d4a6a
Studio                  : 0.460.0
Preview Features        : filterJson, interactiveTransactions

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:1
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
tomhoulecommented, Jun 2, 2022

It’s a rule not only for optional 1:1 relations but for all 1:1 relations. The reason it is exists is that without a unique index on the referencing side, the relation can become a 1:many relation in the database. There is a twist on mongo: on SQL databases, unique indexes ignore null values, only non-null values are checked for uniqueness. If I remember correctly, it isn’t the case on mongo, and a quick check in the documentation makes it look like it just can’t work that way.

This needs some more thought and investigation.

One less-than-ideal but working solution / workaround you can use is to change the relation to be one-to-many, like this:


model Car {
  id            String  @id @map("_id")
  activeOfferId String? @unique
  activeOffer   Offer?  @relation("ActiveOffer", references: [id], fields: [activeOfferId], onDelete: NoAction, onUpdate: NoAction)
  offers        Offer[]
}

model Offer {
  id        String @id @map("_id")
  carId     String
  car       Car    @relation(references: [id], fields: [carId], onDelete: NoAction, onUpdate: NoAction)
  activeCar Car[]   @relation("ActiveOffer")
}

It won’t enforce that there is at most one car per offer, but it would be the same with your suggestion of not enforcing a unique index at all.

0reactions
aladinfluxcommented, Jul 27, 2022

None so far, the only way is to use an array instead of a single field

Read more comments on GitHub >

github_iconTop Results From Across the Web

Data model (Reference) - Prisma
With this model definition, Prisma automatically maps the Comment model to the comments ... Optional and mandatory fields. Relational databases. MongoDB.
Read more >
Using Prisma with MongoDB
This guide discusses the concepts behind using Prisma and MongoDB, explains the commonalities and differences between MongoDB and other database providers, ...
Read more >
Relations (Reference) - Prisma
For MongoDB, Prisma currently uses a normalized data model design, which means that documents reference each other by ID in a similar way...
Read more >
Prisma schema API (Reference)
provider, Yes, String ( postgresql , mysql , sqlite , sqlserver , mongodb , cockroachdb ) ... relationMode, No, String ( foreignKeys ,...
Read more >
Many-to-many relations - Prisma
Prisma schema syntax and the implementation in the underlying database differs between relational databases and MongoDB. Relational databases. In relational ...
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