如何减少 Prisma select(或包括)字段代码行
How to reduce Prisma select(or include) field code line
我正在用 prisma + express + javascript + mysql
开发
prisma 版本是 2.28,
我在使用 prisma 时遇到问题。
当模型是
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")
}
如果我想与用户一起查找配置文件数据 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);
}
};
代码行增加很多..
我可以分别找到用户 table 和配置文件 table,但嵌套查询用于最小化数据库访问。
项目越大,情况越糟。
好像是DB结构不对,但是更换成本已经太高了,不知道哪种方式最好。
感谢您的帮助
除非您需要手动控制确切获取哪些字段,否则最好使用 include
关键字。
这是一个更简洁的查询版本,使用 include
关键字而不是 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);
}
};
您在评论中提到您想要省略的唯一字段是 password
。在这里,我在获取数据后使用 delete
关键字手动省略了该字段。目前没有 Prisma 功能可以明确“排除”某些字段但保留其他所有字段。但是,此功能目前正在开发中,应该很快就会可用。您可以在 this github issue.
中跟踪进度
我正在用 prisma + express + javascript + mysql
开发
prisma 版本是 2.28,
我在使用 prisma 时遇到问题。
当模型是
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")
}
如果我想与用户一起查找配置文件数据 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);
}
};
代码行增加很多..
我可以分别找到用户 table 和配置文件 table,但嵌套查询用于最小化数据库访问。
项目越大,情况越糟。
好像是DB结构不对,但是更换成本已经太高了,不知道哪种方式最好。
感谢您的帮助
除非您需要手动控制确切获取哪些字段,否则最好使用 include
关键字。
这是一个更简洁的查询版本,使用 include
关键字而不是 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);
}
};
您在评论中提到您想要省略的唯一字段是 password
。在这里,我在获取数据后使用 delete
关键字手动省略了该字段。目前没有 Prisma 功能可以明确“排除”某些字段但保留其他所有字段。但是,此功能目前正在开发中,应该很快就会可用。您可以在 this github issue.