限制
Prisma Client Python 存在两种形式的限制,第一种 由于 mypy 的功能缺失/性能问题,可以通过切换到使用 pyright instead
来重新启用。 第二种 由于 Python 类型系统无法准确表示某些场景。
默认类型限制
注意
强烈建议使用 pyright 作为 Prisma Client Python 应用程序的首选类型检查器。
由于 mypy 的限制,某些类型不像预期的那样明确,因此无法被视为完全类型安全,但是 mypy 强加的所有限制都可以通过切换到 pyright 以及 配置 prisma 来使用递归类型来消除。
移除限制
您可以通过使用 pyright 以及 配置 prisma 来使用递归类型来捕获类型检查期间的所有错误。
通过关系字段过滤
Prisma 支持根据关联记录值搜索记录。但是,使用 mypy 对此功能进行类型检查会导致 mypy 挂起并最终崩溃。
因此,这些类型已被扩展,这意味着 mypy 在根据关联字段进行过滤时不会捕获错误,例如,以下代码不会引发任何 mypy 错误,但是会在运行时引发错误。
from prisma import Prisma
async def main(db: Prisma) -> None:
user = await db.user.find_first(
where={
'profile': {
'is': {
'an_invalid_value': 'foo',
},
},
}
)
复杂的分组参数
Mypy 不支持 Literal TypeVars,这意味着以下无效代码在类型检查时不会产生错误
results = await Profile.prisma().group_by(
by=['country'],
order={
# city has to be included in the `by` argument to be valid
'city': True,
}
)
可以通过切换到 pyright 以及 配置 prisma 来使用递归类型来揭示此错误。
Python 限制
由于 Python 无法表达性地处理输入类型,因此类型安全性存在一些限制。虽然可以绕过这个问题,因为 Prisma Client Python 代码是自动生成的,但我们需要在性能和正确性之间取得平衡。
这些限制只影响整个客户端 API 中一个查询方法的2个参数。
分组记录
解释
某些过滤器只能在被分组的字段上执行(即在 by
参数中),这在 Python 中无法以任何精度进行类型化。可以限制字典键,但无法像使用标准 TypedDict
一样将字典键与特定类型匹配。
例如,order
参数可以正确地限制可用键,因为所有值都具有相同的类型
results = await Profile.prisma().group_by(
by=['city'],
order={
'city': 'asc',
# this will error as 'country' is not present in the `by` argument
'country': 'desc',
},
)
然而,由于所有字典值类型不同,使用 having
参数无法实现这一点。
# this error will NOT be caught by static type checkers!
# but it will raise an error at runtime
results = await Profile.prisma().group_by(
by=['city'],
having={
'views': {
'gt': 50,
},
},
)
限制
排序参数
order
参数一次只能接受一个字段。
以下示例将通过类型检查,但在运行时会引发错误。
results = await Profile.prisma().group_by(
by=['city', 'country'],
order={
'city': 'asc',
'country': 'desc',
},
)
Having 参数
having
参数只接受 by
参数中存在的字段 **或** 聚合过滤器。
例如
# this will pass type checks but will raise an error at runtime
# as 'views' is not present in the `by` argument
await Profile.prisma().group_by(
by=['country'],
count=True,
having={
'views': {
'gt': 50,
},
},
)
# however this will pass both type checks and at runtime!
await Profile.prisma().group_by(
by=['country'],
count=True,
having={
'views': {
'_avg': {
'gt': 50,
},
},
},
)