跳至内容


Prisma Client Python

Python 的类型安全数据库访问


什么是 Prisma Client Python?

Prisma Client Python 是一个基于 Prisma 的下一代 ORM,从头开始设计,旨在易于使用和正确性。

Prisma 是一个 TypeScript ORM,为您的数据库提供零成本类型安全,但不用担心,Prisma Client Python 交互 使用 Rust 与 Prisma 交互,您不需要 Node 或 TypeScript。

Prisma Client Python 可用于任何 Python 后端应用程序。这可以是 REST API、GraphQL API 或任何其他需要数据库的东西。

GIF showcasing Prisma Client Python usage

请注意,已知唯一支持此形式自动完成的语言服务器是 Pylance / Pyright。

为什么要使用 Prisma Client Python?

与其他 Python ORM 不同,Prisma Client Python 是 **完全类型安全的**,并提供对 **使用和不使用** async 的原生支持。您只需在 指定您想在项目中使用的客户端类型,即可在 Prisma 模式文件 中进行操作。

然而,Prisma Client Python 提供的 arguably 最好的功能是 自动完成支持(见上图 GIF)。这使得编写数据库查询比以往任何时候都更容易!

核心功能

支持的数据库提供商

  • PostgreSQL
  • MySQL
  • SQLite
  • CockroachDB
  • MongoDB(实验性)
  • SQL Server(实验性)

支持

有任何问题或需要帮助使用 Prisma?加入 社区 Discord

如果您不想加入 Discord,您也可以

Prisma 如何工作?

本节提供了关于 Prisma 工作原理及其最重要的技术组件的高级概述。如需更深入的介绍,请访问 文档

Prisma 模式

每个使用 Prisma 工具包中的工具的项目都从一个 Prisma 模式文件 开始。Prisma 模式允许开发人员使用直观的数据库建模语言定义其应用程序模型。它还包含与数据库的连接,并定义了一个生成器

// database
datasource db {
  provider = "sqlite"
  url      = "file:database.db"
}

// generator
generator client {
  provider             = "prisma-client-py"
  recursive_type_depth = 5
}

// data models
model Post {
  id        Int     @id @default(autoincrement())
  title     String
  content   String?
  views     Int     @default(0)
  published Boolean @default(false)
  author    User?   @relation(fields: [author_id], references: [id])
  author_id Int?
}

model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  posts Post[]
}

在这个模式中,您配置三件事

  • 数据源:指定您的数据库连接。在本例中,我们使用本地 SQLite 数据库,但您也可以使用环境变量。
  • 生成器:指示您要生成 Prisma Client Python。
  • 数据模型:定义您的应用程序模型。

本页面的重点是生成器,因为这是 Prisma Client Python 中唯一特定于它的部分。您可以在各自的文档页面上了解更多关于数据源数据模型的信息。

Prisma 生成器

一个 Prisma 模式可以定义一个或多个生成器,由 generator 块定义。

生成器决定在运行 prisma generate 命令时创建哪些资产。provider 值定义了将创建哪个 Prisma Client。在本例中,由于我们想要生成 Prisma Client Python,因此我们使用 prisma-client-py 值。

您还可以使用 output 选项定义客户端将生成的位置。默认情况下,Prisma Client Python 将生成到其安装位置,无论是在虚拟环境中、全局 Python 安装中,还是任何其他可以从 Python 包中导入的位置。

有关更多选项,请参阅配置 Prisma Client Python


使用 Prisma Client Python 访问您的数据库

只想尝试使用 Prisma Client Python 而不必担心任何设置?您可以在 gitpod 上在线试用。

安装 Prisma Client Python

任何 Python 项目的第一步都应该是设置一个虚拟环境,以将安装的包与其他 Python 项目隔离开来,但这超出了本页面的范围。

在本例中,我们将使用异步客户端,如果您想使用同步客户端,请参阅设置同步客户端

pip install -U prisma

生成 Prisma Client Python

现在我们已经安装了 Prisma Client Python,我们需要实际生成客户端才能访问数据库。

将上面显示的 Prisma 模式文件复制到项目根目录中的 schema.prisma 文件中,然后运行

prisma db push

此命令将把数据模型添加到您的数据库并生成客户端,您应该会看到类似以下内容

Prisma schema loaded from schema.prisma
Datasource "db": SQLite database "database.db" at "file:database.db"

SQLite database database.db created at file:database.db


🚀  Your database is now in sync with your schema. Done in 26ms

✔ Generated Prisma Client Python to ./.venv/lib/python3.9/site-packages/prisma in 265ms

需要注意的是,每当您对 schema.prisma 文件进行更改时,您都需要重新生成客户端,您可以通过运行 prisma generate --watch 自动执行此操作。

最简单的异步 Prisma Client Python 应用程序将类似于以下内容

import asyncio
from prisma import Prisma

async def main() -> None:
    prisma = Prisma()
    await prisma.connect()

    # write your queries here
    user = await prisma.user.create(
        data={
            'name': 'Robert',
            'email': 'robert@craigie.dev'
        },
    )

    await prisma.disconnect()

if __name__ == '__main__':
    asyncio.run(main())

或类似于以下内容

import asyncio
from prisma import Prisma
from prisma.models import User

async def main() -> None:
    db = Prisma(auto_register=True)
    await db.connect()

    # write your queries here
    user = await User.prisma().create(
        data={
            'name': 'Robert',
            'email': 'robert@craigie.dev'
        },
    )

    await db.disconnect()

if __name__ == '__main__':
    asyncio.run(main())

查询示例

有关您可以使用 Prisma Client Python 执行的更完整的查询列表,请参阅文档

所有查询方法都返回 pydantic 模型

从数据库中检索所有 User 记录

users = await db.user.find_many()

在每个返回的 User 对象上包含 posts 关系

users = await db.user.find_many(
    include={
        'posts': True,
    },
)

检索所有包含 "prisma"Post 记录

posts = await db.post.find_many(
    where={
        'OR': [
            {'title': {'contains': 'prisma'}},
            {'content': {'contains': 'prisma'}},
        ]
    }
)

在同一个查询中创建一个新的 User 和一个新的 Post 记录

user = await db.user.create(
    data={
        'name': 'Robert',
        'email': 'robert@craigie.dev',
        'posts': {
            'create': {
                'title': 'My first post from Prisma!',
            },
        },
    },
)

更新现有的 Post 记录

post = await db.post.update(
    where={
        'id': 42,
    },
    data={
        'views': {
            'increment': 1,
        },
    },
)

与静态类型检查器一起使用

所有 Prisma Client Python 方法都完全静态类型化,这意味着你可以在不运行代码的情况下轻松地捕获代码中的错误!

有关更多详细信息,请参阅 文档

Prisma Client Python 如何与 Prisma 交互?

Prisma Client Python 连接到数据库并使用 Prisma 基于 Rust 的查询引擎执行查询,该引擎的源代码可以在此处找到:https://github.com/prisma/prisma-engines。

Prisma Client Python 公开了一个 CLI 接口,它包装了 Prisma CLI。这是通过下载一个 Node 二进制文件来实现的,如果你还没有在你的机器上安装 Node,可以使用 npm 安装 CLI 并使用 Node 运行 CLI。

CLI 接口与标准 Prisma CLI 完全相同,并具有 一些额外的命令

关联

Prisma Client Python 不是 Prisma 的官方产品,尽管它得到了 Prisma 的慷慨赞助。

改进空间

Prisma Client Python 是一个相当新的项目,因此有一些功能缺失或不完整。

查询参数的自动完成

Prisma Client Python 查询参数使用 TypedDict 类型。Python 生态系统中对这些类型的完成支持现在已经相当广泛。本节仅用于记录支持情况。

支持的编辑器/扩展

  • VSCode 与 pylance v2021.9.4 或更高版本
  • Sublime Text 与 LSP-Pyright v1.1.196 或更高版本
  • PyCharm 2022.1 EAP 3 添加了对完成 TypedDict 的支持
  • 不幸的是,这还不适用于 Prisma Client Python,请参阅 此问题
  • 任何支持语言服务器协议并具有支持 Pyright v1.1.196 或更高版本的扩展的编辑器
  • vim 和 neovim 与 coc.nvim
  • emacs
user = await db.user.find_first(
    where={
        '|'
    }
)

假设光标位于 | 的位置,IDE 应该建议以下完成

  • id
  • 电子邮件
  • 姓名
  • 帖子

性能

目前尚未进行任何关于改进 Prisma Client Python 查询性能的工作,但它们应该相当快,因为核心查询构建和连接处理由 Prisma 完成。性能是未来将要改进的方面,并且有很大的改进空间。

支持的平台

Windows、MacOS 和 Linux 均获得官方支持。

版本保证

Prisma Client Python 稳定。

重大变更将被记录并以以下格式发布在新的 **次要** 版本中。

主要.次要.修补程序

新版本计划每两周发布一次,但由于这是一个个人项目,因此无法保证会严格遵守此计划。

贡献

我们使用 常规提交(也称为语义提交)来确保一致且描述性的提交消息。

有关更多信息,请参阅 贡献文档

归属

如果没有 prisma 中出色团队的工作,这个项目是不可能实现的。

@steebchenprisma-client-go 上的工作表示衷心的感谢,这对于该项目的创建非常有帮助。

此自述文件也深受 prisma/prisma 存储库中自述文件的启发。