> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-vortex-format.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Использование Prisma с ClickHouse Managed Postgres

> Подключите приложение на TypeScript к ClickHouse Managed Postgres с помощью Prisma ORM, выполняйте миграции через Prisma Migrate и отправляйте запросы через PgBouncer с проверкой сертификата TLS

export const BetaBadge = ({link, galaxyTrack, galaxyEvent}) => {
  if (link) {
    return <a href={link} target="_blank" rel="noopener noreferrer" className="betaBadge" onClick={galaxyTrack && galaxyEvent ? galaxyOnClick(galaxyEvent) : undefined}>
                <span>Бета</span>
            </a>;
  }
  return <a href="https://clickhouse.com/docs/reference/settings/beta-and-experimental-features#beta-features" className="betaBadge">
            <span>Возможность в статусе бета</span>
        </a>;
};

<BetaBadge link="https://clickhouse.com/cloud/postgres" galaxyTrack={true} galaxyEvent="docs.managed-postgres.guides-prisma-beta" />

[Prisma ORM](https://www.prisma.io/orm) — это ORM для TypeScript с декларативной схемой, инструментом миграций (Prisma Migrate) и генерируемым типобезопасным клиентом. В этом руководстве вы подключите Prisma к ClickHouse Managed Postgres, создадите таблицу с помощью миграции и будете выполнять к ней запросы из скрипта и через небольшую HTTP-конечную точку.

В руководстве используется Prisma ORM 7 (проверено на версии `7.10.0`) — текущий стабильный релиз.

<h2 id="prerequisites">
  Предварительные требования
</h2>

* Node.js 20.19, 22.12 или 24 и выше
* Сервис ClickHouse Managed Postgres
* [`psql`](https://www.postgresql.org/download/) для создания базы данных. Оператор `CREATE DATABASE` также можно выполнить в [консоли SQL](/ru/integrations/connectors/sql-clients/sql-console).
* В macOS: [Docker](https://docs.docker.com/get-started/get-docker/) для запуска Prisma Migrate (см. [Выполнение миграции](#migrate))

<h2 id="create-service">
  Создание сервиса ClickHouse Managed Postgres
</h2>

В консоли ClickHouse Cloud нажмите **New service** и выберите **Postgres**. Инстанс будет готов через несколько минут. Пошаговое описание процесса приведено в [кратком руководстве по началу работы](/ru/products/managed-postgres/quickstart).

<h2 id="connection-details">
  Получите сведения о подключении
</h2>

Нажмите **Connect** на левой боковой панели вашего сервиса. В открывшемся модальном окне отображаются имя пользователя, пароль, сервер и порт, а также готовые строки подключения.

В этом руководстве используются два соединения, поскольку в Prisma есть два компонента, которые обращаются к базе данных:

* **Ваше приложение (Prisma Client)** подключается **через PgBouncer** на порту `6432`. PgBouncer объединяет соединения в пул, поэтому множество процессов приложения или serverless-инстансов могут совместно использовать небольшое число backend-соединений Postgres.
* **Prisma CLI (Prisma Migrate)** подключается **напрямую** на порту `5432`. Во время работы Prisma Migrate захватывает рекомендательную блокировку (advisory lock) на уровне сеанса. В режиме пулинга транзакций PgBouncer эта блокировка может так и остаться на backend-соединении из пула, которое затем обслуживает других клиентов, и последующие миграции будут ждать её снятия.

В верхней части модального окна переключайтесь между **Directly** и **via PgBouncer**, чтобы увидеть порт для каждого варианта. Сервер и учётные данные для обоих соединений одинаковы — отличается только порт.

Выбрав **via PgBouncer**, нажмите **Download CA‑сертификат**. Если выбран вариант **Directly**, сначала включите **Use SSL** — только тогда появится эта кнопка. Файл называется `<service-name>-ca-certificate.pem`. Его также можно найти в разделе **Settings → CA‑сертификат**. Сертификат уникален для вашего инстанса и используется для подключения с `sslmode=verify-full`: этот режим проверяет, что вы подключаетесь именно к своему серверу.

<h2 id="setup">
  Настройка проекта
</h2>

Создайте проект на TypeScript и установите Prisma CLI, Prisma Client, адаптер драйвера [node-postgres](https://node-postgres.com/) и `dotenv`:

```bash theme={null}
mkdir hello-prisma
cd hello-prisma
npm init -y
npm pkg set type=module
npm install typescript tsx @types/node @types/pg --save-dev
npm install prisma@7 --save-dev
npm install @prisma/client@7 @prisma/adapter-pg pg dotenv
```

<Note>
  Явно укажите версии при установке: `prisma@7` и `@prisma/client@7`. На момент написания этого руководства npm-тег `latest` пакета `prisma` указывает на релиз-кандидат Prisma 8, который настраивается иначе, чем описано здесь.
</Note>

Создайте файл `tsconfig.json`:

```json theme={null}
{
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "bundler",
    "target": "ES2023",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "types": ["node"]
  }
}
```

<Tip>
  **Добавляете в существующее приложение?**

  Пропустите `mkdir`, `npm init` и создание `tsconfig.json`. В своём проекте выполните `npm install tsx @types/pg prisma@7 --save-dev` и `npm install @prisma/client@7 @prisma/adapter-pg pg dotenv`, а затем переходите к разделу [Инициализация Prisma](#init).
</Tip>

<h2 id="init">
  Инициализация Prisma
</h2>

<Steps>
  <Step title="Запустите prisma init">
    ```bash theme={null}
    npx prisma init --datasource-provider postgresql --output ../generated/prisma
    ```

    Эта команда создаёт `prisma/schema.prisma` и файл конфигурации Prisma `prisma7.config.ts`, добавляет плейсхолдер `DATABASE_URL` в `.env`, а сгенерированный клиент — в `.gitignore` (при необходимости создавая эти файлы), а также устанавливает навыки Prisma для AI-агентов для написания кода. Начиная с версии Prisma 7.10, файл конфигурации называется `prisma7.config.ts`, чтобы не возникало конфликта с форматом Prisma 8.
  </Step>

  <Step title="Добавьте CA‑сертификат">
    Переместите скачанный CA‑сертификат в корень проекта и переименуйте его в `ca-certificate.pem`:

    ```bash theme={null}
    mv ~/Downloads/<service-name>-ca-certificate.pem ca-certificate.pem
    ```

    Относительные пути к сертификатам вычисляются от каталога, в котором выполняются команды, поэтому запускайте все команды из этого руководства из корня проекта.
  </Step>
</Steps>

<h2 id="configure">
  Настройка соединения
</h2>

<Steps>
  <Step title="Создайте базу данных">
    Создайте базу данных для приложения. Замените `<PASSWORD>` и хост значениями из модального окна **Connect**:

    ```bash theme={null}
    psql "postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/postgres?sslmode=verify-full&sslrootcert=ca-certificate.pem" -c "CREATE DATABASE guide_prisma;"
    ```

    ```text theme={null}
    CREATE DATABASE
    ```
  </Step>

  <Step title="Задайте URL-адреса соединений">
    В файле `.env` замените плейсхолдер `DATABASE_URL`, добавленный командой `prisma init`, двумя URL-адресами соединений, оба из которых указывают на базу данных `guide_prisma`. Используйте пароль из модального окна Connect:

    ```bash theme={null}
    # Prisma Client (ваше приложение): через PgBouncer, порт 6432
    DATABASE_URL="postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:6432/guide_prisma?sslmode=verify-full&sslrootcert=ca-certificate.pem"

    # Prisma CLI (миграции): прямое соединение, порт 5432
    DIRECT_URL="postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/guide_prisma?sslmode=require&sslaccept=strict&sslcert=ca-certificate.pem"
    ```

    В этих URL используются разные параметры TLS, поскольку их считывают разные драйверы:

    * **`DATABASE_URL`** считывает node-postgres через `@prisma/adapter-pg`. Он поддерживает стандартные параметры `sslmode=verify-full&sslrootcert=...` — те же, что указаны в модальном окне Connect.
    * **`DIRECT_URL`** считывает движок схем Prisma CLI, у которого свои параметры: `sslcert` — путь к CA‑сертификату, а `sslaccept=strict` включает проверку сертификата и имени хоста.

    <Warning>
      Не используйте `sslmode=verify-full&sslrootcert=...` в URL для Prisma CLI. Движок схем игнорирует `sslrootcert`, а без `sslaccept=strict` вообще не проверяет сертификат сервера: соединение будет зашифровано, но подлинность сервера не будет подтверждена.
    </Warning>
  </Step>

  <Step title="Направьте Prisma CLI на прямое соединение">
    Замените содержимое файла `prisma7.config.ts`:

    ```typescript theme={null}
    import "dotenv/config";
    import { defineConfig, env } from "prisma/config";

    export default defineConfig({
      schema: "prisma/schema.prisma",
      migrations: {
        path: "prisma/migrations",
      },
      datasource: {
        url: env("DIRECT_URL"),
      },
    });
    ```

    В Prisma 7 URL из файла конфигурации использует только CLI. Prisma Client получает соединение от адаптера драйвера, который настраивается в разделе [Запросы к базе данных](#query).
  </Step>
</Steps>

<h2 id="migrate">
  Определение схемы и выполнение миграции
</h2>

<Steps>
  <Step title="Добавьте модель">
    Добавьте модель `Todo` в конец файла `prisma/schema.prisma`:

    ```prisma theme={null}
    model Todo {
      id        Int      @id @default(autoincrement())
      title     String
      done      Boolean  @default(false)
      createdAt DateTime @default(now())
    }
    ```
  </Step>

  <Step title="Выполните миграцию">
    В Linux запустите Prisma Migrate напрямую:

    ```bash theme={null}
    npx prisma migrate dev --name init
    ```

    В macOS выполните ту же команду в Linux-контейнере:

    ```bash theme={null}
    docker run --rm -it -v "$PWD":/app -w /app node:24 npx prisma migrate dev --name init
    ```

    <Warning>
      ClickHouse Managed Postgres поддерживает только TLS 1.3. В macOS движок схем Prisma CLI использует системную библиотеку TLS, которая не может установить соединение с такими настройками. Команда завершается ошибкой `P1011: Error opening a TLS connection: One or more parameters passed to a function were not valid`, а если удалить `sslcert`, — ошибкой `bad protocol version` ([prisma/orm#29600](https://github.com/prisma/orm/issues/29600)). Проблема касается только команд CLI, которые подключаются к базе данных, например `prisma migrate` и `prisma db pull`. На Prisma Client она не влияет, поскольку он подключается через node-postgres. Чтобы обойти проблему, запускайте CLI в Linux-контейнере или в конвейере CI на базе Linux.
    </Warning>

    Prisma создаёт SQL-миграцию в `prisma/migrations/` и применяет её:

    ```text theme={null}
    Applying migration `20260930165244_init`

    The following migration(s) have been created and applied from new schema changes:

    prisma/migrations/
      └─ 20260930165244_init/
        └─ migration.sql

    Your database is now in sync with your schema.
    ```
  </Step>

  <Step title="Сгенерируйте Prisma Client">
    ```bash theme={null}
    npx prisma generate
    ```

    Клиент генерируется в каталог `generated/prisma`. Эта команда не подключается к базе данных, поэтому её можно запускать на любой платформе.
  </Step>
</Steps>

<h2 id="query">
  Выполнение запросов к базе данных
</h2>

<Steps>
  <Step title="Создайте Prisma Client">
    Создайте `lib/prisma.ts`. Адаптер `PrismaPg` подключается через PgBouncer, используя `DATABASE_URL`:

    ```typescript theme={null}
    import "dotenv/config";
    import { PrismaPg } from "@prisma/adapter-pg";
    import { PrismaClient } from "../generated/prisma/client";

    const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL });

    export const prisma = new PrismaClient({ adapter });
    ```

    <Tip>
      **Настраивать PgBouncer не нужно**

      `@prisma/adapter-pg` отправляет каждый запрос как безымянный подготовленный оператор и никогда не выполняет `DEALLOCATE`, поэтому он совместим с режимом пулинга транзакций PgBouncer. Адаптер без ошибок обрабатывает сотни различных запросов, параллельно выполняемых на backend-соединениях из пула. Параметр URL `pgbouncer=true` из старых версий Prisma не нужен: с адаптером драйвера он ни на что не влияет.
    </Tip>
  </Step>

  <Step title="Выполните CRUD-запросы">
    Создайте `script.ts`:

    ```typescript theme={null}
    import { prisma } from "./lib/prisma";

    async function main() {
      // Создание
      const todo = await prisma.todo.create({
        data: { title: "Connect Prisma to ClickHouse Managed Postgres" },
      });
      console.log("Created:", todo);

      // Чтение
      const open = await prisma.todo.findMany({ where: { done: false } });
      console.log("Open todos:", open.length);

      // Обновление
      const updated = await prisma.todo.update({
        where: { id: todo.id },
        data: { done: true },
      });
      console.log("Updated:", updated);

      // Удаление
      await prisma.todo.delete({ where: { id: todo.id } });
      console.log("Deleted todo", todo.id);
    }

    main().finally(() => prisma.$disconnect());
    ```

    Запустите скрипт:

    ```bash theme={null}
    npx tsx script.ts
    ```

    ```text theme={null}
    Created: {
      id: 1,
      title: 'Connect Prisma to ClickHouse Managed Postgres',
      done: false,
      createdAt: 2026-09-30T16:52:57.116Z
    }
    Open todos: 1
    Updated: {
      id: 1,
      title: 'Connect Prisma to ClickHouse Managed Postgres',
      done: true,
      createdAt: 2026-09-30T16:52:57.116Z
    }
    Deleted todo 1
    ```
  </Step>

  <Step title="Предоставьте доступ к данным по HTTP">
    Создайте `server.ts` — минимальный HTTP-сервер, который создаёт задачи по запросу `POST /todos` и возвращает их список на любой запрос `GET`:

    ```typescript theme={null}
    import { createServer } from "node:http";
    import { prisma } from "./lib/prisma";

    const port = Number(process.env.PORT ?? 3000);

    createServer(async (req, res) => {
      if (req.method === "POST" && req.url === "/todos") {
        let body = "";
        for await (const chunk of req) body += chunk;
        const todo = await prisma.todo.create({ data: { title: JSON.parse(body).title } });
        res.writeHead(201, { "Content-Type": "application/json" });
        res.end(JSON.stringify(todo));
        return;
      }

      const todos = await prisma.todo.findMany({ orderBy: { id: "asc" } });
      res.writeHead(200, { "Content-Type": "application/json" });
      res.end(JSON.stringify(todos, null, 2));
    }).listen(port, () => console.log(`Listening on http://localhost:${port}`));
    ```

    Запустите сервер:

    ```bash theme={null}
    npx tsx server.ts
    ```

    В другом терминале добавьте две задачи:

    ```bash theme={null}
    curl -X POST localhost:3000/todos -H "Content-Type: application/json" -d '{"title": "Try Prisma with ClickHouse Managed Postgres"}'
    curl -X POST localhost:3000/todos -H "Content-Type: application/json" -d '{"title": "Add a read replica"}'
    ```

    Чтобы увидеть их, откройте в браузере [http://localhost:3000/todos](http://localhost:3000/todos). Ответ будет выглядеть так:

    ```json theme={null}
    [
      {
        "id": 2,
        "title": "Try Prisma with ClickHouse Managed Postgres",
        "done": false,
        "createdAt": "2026-09-30T16:53:06.098Z"
      },
      {
        "id": 3,
        "title": "Add a read replica",
        "done": false,
        "createdAt": "2026-09-30T16:53:06.184Z"
      }
    ]
    ```
  </Step>
</Steps>

<h2 id="verify">
  Проверка в консоли SQL
</h2>

В консоли ClickHouse Cloud откройте **консоль SQL** для своего сервиса, разверните свою базу данных и схему `public`, затем выберите таблицу `Todo`. Там же вы увидите таблицу `_prisma_migrations`, в которой Prisma Migrate фиксирует применённые миграции.

Таблица `Todo` содержит две строки, добавленные через конечную точку HTTP:

| id | title | done | createdAt |
| - | - | - | - |
| 2 | Try Prisma with ClickHouse Managed Postgres | false | 2026-09-30 16:53:06.098 |
| 3 | Add a read replica | false | 2026-09-30 16:53:06.184 |

<h2 id="troubleshooting">
  Устранение неполадок
</h2>

| Ошибка | Причина и решение |
| - | - |
| `P1011: Error opening a TLS connection: One or more parameters passed to a function were not valid` или `bad protocol version` | Prisma CLI запущен на macOS. Запустите его в Linux‑контейнере, как показано в разделе [Выполнение миграции](#migrate). |
| `P1011: ... certificate verify failed` | Prisma CLI не может проверить подлинность сервера. Убедитесь, что `sslcert` в `DIRECT_URL` указывает на CA‑сертификат вашего инстанса. |
| `P1011: ... cert file not found` | Неверно указан путь `sslcert` в `DIRECT_URL`. Запускайте CLI из корневого каталога проекта или укажите абсолютный путь. |
| `unable to verify the first certificate` | Prisma Client не может проверить подлинность сервера. Убедитесь, что `sslrootcert` в `DATABASE_URL` указывает на CA‑сертификат вашего инстанса. |
| `ENOENT: no such file or directory` | Неверно указан путь `sslrootcert` в `DATABASE_URL`. Запускайте приложение из корневого каталога проекта или укажите абсолютный путь. |

<h2 id="next-steps">
  Дальнейшие шаги
</h2>

* [Соединение](/ru/products/managed-postgres/connection): строки соединения, PgBouncer и TLS
* [Настройки](/ru/products/managed-postgres/settings): настройка параметров Postgres и PgBouncer
* [Реплики для чтения](/ru/products/managed-postgres/read-replicas): масштабирование рабочих нагрузок с преобладанием операций чтения
* [Локальная разработка](/ru/products/managed-postgres/local-development): разработка с локальным Postgres в Docker
* [Prisma Migrate в продакшне](https://www.prisma.io/docs/orm/prisma-migrate/workflows/development-and-production): используйте `prisma migrate deploy` в конвейере CI
