自定义生成器
想用你的 prisma 模式做任何事吗?
你可以轻松地用 python 编写你自己的 prisma 生成器!
它是如何工作的?
Prisma 生成器包含两个步骤
- 生成器元数据
- 资产生成
元数据
元数据步骤由 Prisma 用于收集有关您的生成器的信息,包括以下信息:
- 生成器的名称
- 默认输出位置
此数据在 Prisma Client Python 中使用 Manifest
模型表示
from prisma.generator import BaseGenerator, Manifest
class MyGenerator(BaseGenerator):
def get_manifest(self) -> Manifest:
return Manifest(
name='Custom Prisma Generator'
default_output='out.txt',
)
生成
Prisma 在生成步骤中向生成器发送 Prisma Schema DMMF,这是您的 Prisma Schema 的 AST 形式。
DMMF 在 Prisma Client Python 中使用 Data
模型表示
from pathlib import Path
from prisma.generator import BaseGenerator, DefaultData
class MyGenerator(BaseGenerator):
# some code has been ommited from this example for brevity
# the full boilerplate example can be found below
def generate(self, data: DaDefaultDatata) -> None:
content = [
model.name
for model in data.dmmf.datamodel.models
]
file = Path(data.generator.output.value)
file.write_text('\n'.join(content))
警告
对 DMMF 结构的更改不被视为重大更改
样板
开始编写您自己的 Prisma 生成器所需的最小代码
from prisma.generator import BaseGenerator, Manifest, DefaultData
class MyGenerator(BaseGenerator):
def get_manifest(self) -> Manifest:
return Manifest(
name='My Generator',
default_output='output.txt',
)
def generate(self, data: DefaultData) -> None:
pass
if __name__ == '__main__':
MyGenerator.invoke()
自定义配置选项
您也可以直接在 Prisma Schema 文件中添加自定义配置选项!例如,考虑以下模式
generator my_generator {
provder = "python my_generator.py"
my_option = 1
}
为了支持定义自定义选项,您需要以略微不同的方式定义生成器
from pydantic import BaseModel
from prisma.generator import Manifest, GenericData, GenericGenerator
# custom options must be defined using a pydantic BaseModel
class Config(BaseModel):
my_option: int
# we don't technically need to define our own Data class
# but it makes typing easier
class Data(GenericData[Config]):
pass
# the GenericGenerator[Data] part is what tells Prisma Client Python to use our
# custom Data class with our custom Config class
class MyGenerator(GenericGenerator[Data]):
def get_manifest(self) -> Manifest:
return Manifest(
name='My Custom Generator Options',
default_output='schema.md',
)
def generate(self, data: Data) -> None:
# generate some assets here
pass
if __name__ == '__main__':
MyGenerator.invoke()
示例
在本例中,我们将创建一个简单的生成器,它会创建一个类似于此的 markdown 文件
# My Prisma Schema
This file is automatically generated every time `prisma generate` is ran.
## User Model
## Post Model
创建一个名为 my_generator.py
的新文件,并添加以下代码
from pathlib import Path
from prisma.generator import Manifest, DefaultData, BaseGenerator
TEMPLATE = """
# My Prisma Schema
This file is automatically generated every time `prisma generate` is ran.
"""
MODEL_TEMPLATE = """
## {0.name} Model
"""
class MyGenerator(BaseGenerator):
def get_manifest(self) -> Manifest:
return Manifest(
name='My Cool Generator',
default_output='schema.md',
)
def generate(self, data: DefaultData) -> None:
content = TEMPLATE
for model in data.dmmf.datamodel.models:
content += MODEL_TEMPLATE.format(model)
# make sure you use the output value given in the Prisma DMMF
# as the output location can be customised!
file = Path(data.generator.output.value)
file.write_text(content)
if __name__ == '__main__':
MyGenerator.invoke()
现在,我们只需要在 Prisma Schema 文件中添加一个新的生成器
generator my_generator {
provider = "python my_generator.py"
}
限制
冗余验证
目前无法禁用仅适用于 Prisma Client Python 的任何数据验证。例如,以下模式将引发验证错误,因为字段名称将生成无效的 Python 代码。
model User {
id Int @default(autoincrement())
from String
}
但是,您可能没有生成 Python 代码,甚至可能没有在项目中使用 Prisma Client Python 生成器,这将使此验证错误变得多余。