What Prisma doesn’t have yet
Tags: prisma, webdev, javascript
Published: 2022-12-13 16:59:40

First of all, this is not a post trying to blame Prisma and promote some other alternatives. Instead, I bet Prisma would be the best Typescript ORM dominant in the full-stack world. That’s why I switched to Prisma from TypeORM, which I have used for many years.

All the missing features I will discuss are from the top(most comments) issues of the Prisma GitHub repository. Therefore if you once run into any of them, I suggest you participate in the discussion thread of that issue which you can benefit from:

- Knowing some workaround/hack for this issue.
- Understanding the whole picture of the issue, especially for things you haven’t thought about.
- Seeing the pros and cons of different proposals and voting for the one you like best or even giving your own proposal.

Most importantly, let the community hear your voice and hope it will improve Prisma.

## Custom Attribute

- Issue
  {% embed https://github.com/prisma/prisma/issues/3102 %}

  If I get to pick up only one to be implemented, it will be **Custom Attribute**, without a doubt. Not only because there are several issues that could be resolved by this below:

  - [Support SQL Check constraints #3388](https://github.com/prisma/prisma/issues/3388)
  - [Add exclude in the query arguments #5042](https://github.com/prisma/prisma/issues/5042)
  - [Support adding prefix to an @id field #3391](https://github.com/prisma/prisma/issues/3391)

  But also, this is like opening the door of the extension to the whole community. As Prisma advocates that we use the schema as the single source of truth for the model of our application, I think the prerequisite is that it has a good extension mechanism. Otherwise, Prisma would have to cover all the different cases by itself to achieve that universally.

  Although [Prisma Client Extensions](https://www.prisma.io/docs/concepts/components/prisma-client/client-extensions) feature has come out in version 4.7.0, which allows extending models programmatically in the client, it doesn’t support the advocating of the single source of the truth.

  Since the issue has been open for two years since 2020, and there is not any update from the Prisma team yet, not even in the [Prisma Roadmap](https://www.notion.so/Prisma-Roadmap-50766227b779464ab98899accb98295f), I’m afraid we won’t see it could come in a short time. I could understand that it would complicate the whole framework and add a burden for future updates. But isn’t that something you have to bear if you aim to build a prosperous ecosystem? Moreover, I think that’s really the power of the open-source community we could rely on. 😊

- Workaround

  You can use make use of the comments to put whatever you need there, which could be accessed in the AST of the schema file. You need to implement your own generator to process it. It would be like what [prisma-nestjs-graphql](https://github.com/unlight/prisma-nestjs-graphql) does :

  ```jsx
  model User {
      id String @id @default(cuid())
      /// @HideField()
      password String
      /// @HideField({ output: true, input: true })
      secret String
      /// @HideField({ match: '@(User|Comment)Create*Input' })
      createdAt DateTime @default(now())
  }
  ```

## Soft Delete

- Issue
  {% embed https://github.com/prisma/prisma/issues/3398 %}

  There was only one time I initiative upgrading the TypeORM version because of the official support of **Soft Delete**. See the below benefits I got from it for our SAAS product:

  - Restore the data accidentally deleted by the customer
  - Analyze customer behavior
  - History tracking and audit

  Therefore **Soft Delete** is almost mandatory for me. Lots of people might have a different opinion considering the challenge of the “proper” implementation. That’s why I think it’s up to the ORM to implement it so that we can use it just as simple as what we do for the normal delete. See what [TypeORM](https://typeorm.io/delete-query-builder#soft-delete) provided:

  ```tsx
  @Entity()
  export class User {
    @DeleteDateColumn()
    deletedDate: Date;
  }

  await myDataSource.createQueryBuilder("users").softDelete().where("id = :id", { id: 1 }).execute();
  ```

- Workaround

  I’m not sure whether it’s even a workaround because it’s the official document of Prisma to specify [how to implement the soft delete using middleware](https://www.prisma.io/docs/concepts/components/prisma-client/middleware/soft-delete-middleware). Just take a glance at how long the article is and how many lines of code it contains, and you will see why I treat it as a workaround, and also, I guess that’s the reason why this issue has not been closed yet.

  BTW, I feel using the new feature [Prisma Client Extensions](https://www.prisma.io/docs/concepts/components/prisma-client/client-extensions) aforementioned to implement it might be more straightforward and simpler. Care to try it? 😉

## Type of Json Field

- Issue
  {% embed https://github.com/prisma/prisma/issues/3219 %}
  Since JSON data type has been the first citizen of MySQL, we have used it a lot. It’s kind of like adopting the benefit of NoSQL in the SQL world.

  In TypeORM, it’s really quite easy to use as it’s really very convenient to use. You can even use inline type definition to get type safety like the below:

  ```tsx
  @Entity()
  export class User {
    @PrimaryGeneratedColumn()
    id: number;

    @Column("simple-json")
    profile: { name: string; nickname: string };
  }
  ```

  In Prisma, of course, it’s not as easy as its schema first. But the suggested solution in the issue might be a way to go:

  ```tsx
  json ExtendedUserProfileJson {
      field1  String
      field2  Int
  }

  model User {
    id               Int  @default(autoincrement()) @id
    name             String?
    extendedProfile  ExtendedUserProfileJson
  }
  ```

- Workaround


  You would need manually cast it in your code like below:

  ```tsx
  interface UserProfile {
      field1: string;
      field2: number;
  }

  const user = prismaService.user.findOne(...);
  (user.extendedProfile as UserProfile).field1;
  ```

  And the worse thing is that you don’t get type validation when writing.

## Multiple Connections / Databases / Datasources

- Issue
  {% embed https://github.com/prisma/prisma/issues/2443 %}
  If somehow you have to access some specific data punctually in a separate database/server, this is like a MUST for you.

- Workaround


  You need to create multiple data models like below:

  **In the schema**
  - prisma/schema1.prisma

    ```tsx
    datasource db {
      provider = "postgres"
      url      = env("DB1_URL")
    }

    generator client {
      provider = "prisma-client-js"
      output   = "./generated/client1"
    }

    model Model1 {
      id         Int @id @default(autoincrement())
      model1Name String
    }
    ```

  - prisma/schema2.prisma

    ```tsx
    datasource db {
      provider = "postgres"
      url      = env("DB2_URL")
    }

    generator client {
      provider = "prisma-client-js"
      output   = "./generated/client2"
    }

    model Model2 {
      id         Int @id @default(autoincrement())
      model2Name String
    }
    ```

  **In the code**

  ```tsx
  import { PrismaClient as PrismaClient1 } from "../prisma/generated/client1";
  import { PrismaClient as PrismaClient2 } from "../prisma/generated/client2";

  const client1 = new PrismaClient1();
  const client2 = new PrismaClient2();
  ```

  **In the CLI**

  ```bash
  prisma generate --schema prisma/schema1.prisma
  prisma generate --schema prisma/schema2.prisma
  ```

BTW, if you are using PostgresSQL and would like to query across multiple schemas, you are lucky that they have just released a preview feature for it. Check it out below:

[https://www.prisma.io/docs/guides/database/multi-schema#learn-more-about-the-multischema-preview-feature](https://www.prisma.io/docs/guides/database/multi-schema#learn-more-about-the-multischema-preview-feature)

And leave your feedback about it in the issue:

{% embed https://github.com/prisma/prisma/issues/15077 %}

## Real Time API

- Issue
  {% embed https://github.com/prisma/prisma/issues/298 %}
  I personally didn’t need this until now, but I guess it would be necessary if your business needs some real-time collaboration. I guess another reason why it gets talked about a lot is that it’s the only feature that got missed from [Prisma 1](https://www.prisma.io/docs/guides/upgrade-guides/upgrade-from-prisma-1/how-to-upgrade#feature-parity).

- Workaround


  I guess you have to implement it by yourself or find another solution for this.

---

Introducing [ZenStack](https://zenstack.dev/?utm_campaign=devto&utm_medium=organic&utm_content=what_prisma_doesnot_have):a toolkit that supercharges Prisma ORM. We have managed to resolve the first two issues.  Check out the posts I wrote for it:

{% embed https://dev.to/zenstack/how-to-add-custom-attributes-in-prisma-6i8 %}
{% embed https://dev.to/zenstack/soft-delete-implementation-issues-in-prisma-and-solution-in-zenstack-23fl %}