How to reduce Prisma select(or include) field code line

Viewed 2037

I am developing with prisma + express + javascript + mysql
prisma version is 2.28,
I have a problem while using prisma.
when the model is

model User{
  id              Int           @id @default(autoincrement())
  email           String        @unique @db.VarChar(30)
  password        String?       @db.VarChar(200)
  nickname        String?       @unique @db.VarChar(30)
  profile         Profile?

}
model Profile {
  id             Int              @id @default(autoincrement())
  department     String?          @db.VarChar(50)
  introduce      String?          @db.Text
  createdAt      DateTime
  updatedAt      DateTime?
  user           User             @relation(fields: [userId], references: [id])
  userId         Int
  wellTalent     WellTalent[]
  interestTalent InterestTalent[]
  profileImage   Image?

  @@map(name: "profiles")
}
model InterestTalent {
  id        Int       @id @default(autoincrement())
  contents  String?
  createdAt DateTime
  updatedAt DateTime?
  profile   Profile   @relation(fields: [profileId], references: [id])
  profileId Int

  @@map(name: "interest_talents")
}

model WellTalent {
  id        Int       @id @default(autoincrement())
  contents  String?
  createdAt DateTime
  updatedAt DateTime?
  profile   Profile   @relation(fields: [profileId], references: [id])
  profileId Int

  @@map(name: "well_talents")
}

model Image {
  id        Int       @id @default(autoincrement())
  src       String?   @db.VarChar(200)
  createdAt DateTime
  updatedAt DateTime?
  profile   Profile?  @relation(fields: [profileId], references: [id])
  profileId Int?

  @@map(name: "images")
}

if i want to find the profile data along with user table

const prisma = new PrismaClient();

const findByIdWithProfile = async (id) => {
    try {
        return await prisma.user.findUnique({
            where: { id },
            select: {
                id: true,
                nickname: true,
                email: true,
                profile: {
                    select: {
                        id: true,
                        department: true,
                        introduce: true,
                        wellTalent: {
                            select: {
                                contents: true,
                            },
                        },
                        interestTalent: {
                            select: {
                                contents: true,
                            },
                        },
                        profileImage: {
                            select: {
                                src: true,
                            },
                        },
                    },
                },
            },
        });
    } catch (err) {
        console.error(err);
    }
};

code line is very increase.. i can find User table and Profile table separately, but nest query use to minimize DB access.
bigger the project, the worse it got.
It seems that the DB structure is structured incorrectly, but the cost is already too high to replace, and I do not know which way is the best.
Thanks for your help

1 Answers

Unless you need manual control of exactly which fields are fetched, it's better to go with the include keyword.

Here is a more succinct version of your query with the include keyword instead of select.

const findByIdWithProfile = async (id) => {
    try {
        let data = await prisma.user.findUnique({
            where: { id },
            include: {
                profile: {
                    include: {
                        wellTalent: true,
                        interestTalent: true,
                        profileImage: true,
                    },
                },
            },
        });
        delete data["password"]; // sensitive information we don't want to expose. 
        return data; 
    } catch (err) {
        console.error(err);
    }
};

You mentioned in the comments that the only field you want to omit is password. Here I manually omitted that field using the delete keyword once the data is fetched. There's currently no Prisma feature to explicitly "exclude" certain fields but keep everything else. However, this feature is currently being worked one and should be available soon. You can track progress in this github issue.

Related