我在 Prisma 模式中有这两个表:
model Accounts {
id Int @id @default(autoincrement())
name String @db.VarChar(100)
description String? @db.VarChar(255)
timeZone Int @default(0)
tableBusinessApplication AccountsBusinessApplications[]
}
model AccountsBusinessApplications {
id Int @id @default(autoincrement())
account Accounts @relation(fields: [accountId], references: [id])
accountId Int
name String @db.VarChar(100)
identification String @db.VarChar(100)
secretKey String @db.VarChar(32)
}
我有以下代码:
const name = 'Accounts'
prisma[name].findFirst({
where: { id: 1}
}).then(result => { console.log(result) })
结果我:
{
id: 1,
name: 'test',
description: 'test description',
timeZone: 0
}
但我在里面没有看到“tableBusinessApplication”。如果我只知道第一类名称“Accounts”并且无法在查询中使用“Include”,如何获取所有数据?
我尝试找到如何使用 prisma 类获取字段列表,但似乎什么也没有。
自 Prisma 4 起:
import { Prisma } from '@prisma/client';
console.log("Account fields:", Prisma.dmmf.datamodel.models.find(model => model.name === "Account").fields)
自 Prisma 5 起:
const allowedFields = Object.keys(prisma[this.modelName].fields)
您可以使用 Prisma 的
DMMF
属性来获取模型字段的名称。
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// A `main` function so that you can use async/await
async function main() {
// @ts-ignore
console.log('dmmf', prisma._dmmf.modelMap.Accounts.fields);
}
main()
.catch((e) => {
throw e;
})
.finally(async () => {
await prisma.$disconnect();
});
这是输出
dmmf [
{
name: 'id',
kind: 'scalar',
isList: false,
isRequired: true,
isUnique: false,
isId: true,
isReadOnly: false,
type: 'Int',
hasDefaultValue: true,
default: { name: 'autoincrement', args: [] },
isGenerated: false,
isUpdatedAt: false
},
{
name: 'name',
kind: 'scalar',
isList: false,
isRequired: true,
isUnique: false,
isId: false,
isReadOnly: false,
type: 'String',
hasDefaultValue: false,
isGenerated: false,
isUpdatedAt: false
},
{
name: 'description',
kind: 'scalar',
isList: false,
isRequired: false,
isUnique: false,
isId: false,
isReadOnly: false,
type: 'String',
hasDefaultValue: false,
isGenerated: false,
isUpdatedAt: false
},
{
name: 'timeZone',
kind: 'scalar',
isList: false,
isRequired: true,
isUnique: false,
isId: false,
isReadOnly: false,
type: 'Int',
hasDefaultValue: true,
default: 0,
isGenerated: false,
isUpdatedAt: false
},
{
name: 'tableBusinessApplication',
kind: 'object',
isList: true,
isRequired: true,
isUnique: false,
isId: false,
isReadOnly: false,
type: 'AccountsBusinessApplications',
hasDefaultValue: false,
relationName: 'AccountsToAccountsBusinessApplications',
relationFromFields: [],
relationToFields: [],
isGenerated: false,
isUpdatedAt: false
}
]
请注意,
DMMF
是内部API,未来版本中可能会发生变化。
提供的解决方案对于 Prisma v5.6.0 来说已经过时了。下面是我的不完整但功能性代码,用于从 Prisma 模式读取并生成 JSON,我将其用于 Hygen 的模板生成。
import { readFileSync, writeFileSync } from 'fs'
import { join } from 'path'
interface Field {
name: string;
type: string;
isUnique: boolean;
}
interface UniqueConstraint {
fields: string[];
}
interface Index {
fields: string[];
}
interface Model {
name: string;
tableName?: string; // Database table name if specified
fields: Field[];
uniqueConstraints: UniqueConstraint[];
indexes: Index[];
}
// Basic parsing of model definitions
const parseModels = (schema: string): Model[] => {
const modelRegex = /model (\w+) {([\s\S]*?)^}/gm
let match
const models: Model[] = []
while ((match = modelRegex.exec(schema)) !== null) {
const modelName = match[1]
const modelBody = match[2]
const fields = modelBody.trim().split('\n')
.filter(line => line && !line.startsWith('@') && !line.startsWith('@@'))
.map((line) => {
const [name, type] = line.trim().split(/\s+/)
const isUnique = line.includes('@unique')
if (name.includes('@@')) {
return null
}
return { name, type, isUnique }
}).filter(field => field !== null)
// Extract table mapping
const tableMappingMatch = modelBody.match(/@@map\(["'](.+?)["']\)/)
const tableName = tableMappingMatch ? tableMappingMatch[1] : undefined
// Extract unique constraints
const uniqueConstraints: UniqueConstraint[] = []
const uniqueRegex = /@@unique\(\[([^\]]+)\]\)/g
let uniqueMatch
while ((uniqueMatch = uniqueRegex.exec(modelBody)) !== null) {
const fields = uniqueMatch[1].split(',').map(field => field.trim())
uniqueConstraints.push({ fields })
}
// Extract indexes
const indexes: Index[] = []
const indexRegex = /@@index\(\[([^\]]+)\]\)/g
let indexMatch
while ((indexMatch = indexRegex.exec(modelBody)) !== null) {
const fields = indexMatch[1].split(',').map(field => field.trim())
indexes.push({ fields })
}
models.push({ name: modelName, tableName, fields, uniqueConstraints, indexes })
// const rawFields = modelBody.trim().split('\n').map((line) => {
// let [name, type] = line.trim().split(/\s+/)
// const isArray = type && type.includes('[]')
// const nullable = type && type.endsWith('?')
// if (nullable) {
// type = type.slice(0, -1)
// }
// if (isArray) {
// type = type.replace('[]', '')
// }
// return { name, type, isArray, nullable }
// })
// const cleanFields = [...rawFields].filter(field => field.name && field.name.startsWith('@@') === false)
// const indexes = [...rawFields].filter(field => field.name.startsWith('@@'))
// models.push({ name: modelName, fields: cleanFields, indexes })
}
return models
}
const parsePrismaSchema = (schemaPath: string): Model[] => {
const schema = readFileSync(schemaPath, 'utf8')
return parseModels(schema)
}
const main = () => {
const schemaPath = join(__dirname, '../../prisma/schema.prisma')
const models = parsePrismaSchema(schemaPath)
// console.log(JSON.stringify(models, null, 2))
// write to prisma/schema.json
const schemaJsonPath = join(__dirname, '../../prisma/schema.json')
const schemaJson = JSON.stringify(models, null, 2)
console.log(schemaJson)
writeFileSync(schemaJsonPath, schemaJson)
}
main()