> ## 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.

# Use o Prisma com o ClickHouse Managed Postgres

> Conecte uma aplicação TypeScript ao ClickHouse Managed Postgres com o Prisma ORM, execute migrações com o Prisma Migrate e faça consultas via PgBouncer com TLS verificado

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>Beta</span>
            </a>;
  }
  return <a href="https://clickhouse.com/docs/reference/settings/beta-and-experimental-features#beta-features" className="betaBadge">
            <span>Recurso beta</span>
        </a>;
};

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

O [Prisma ORM](https://www.prisma.io/orm) é um ORM para TypeScript com schema declarativo, uma ferramenta de migração (Prisma Migrate) e um cliente gerado com tipagem segura. Neste guia, você vai conectar o Prisma ao ClickHouse Managed Postgres, criar uma tabela por meio de uma migração e consultá-la a partir de um script e de um pequeno endpoint HTTP.

Este guia usa o Prisma ORM 7 (testado com `7.10.0`), o lançamento estável atual.

<h2 id="prerequisites">
  Pré-requisitos
</h2>

* Node.js 20.19, 22.12 ou 24 (ou posterior)
* Um serviço ClickHouse Managed Postgres
* [`psql`](https://www.postgresql.org/download/), para criar o banco de dados. Você também pode executar a instrução `CREATE DATABASE` no [SQL Console](/pt-BR/integrations/connectors/sql-clients/sql-console).
* No macOS: [Docker](https://docs.docker.com/get-started/get-docker/), para executar o Prisma Migrate (consulte [Executar a migração](#migrate))

<h2 id="create-service">
  Crie um serviço ClickHouse Managed Postgres
</h2>

No console do ClickHouse Cloud, clique em **New service** e selecione **Postgres**. A instância fica pronta em poucos minutos. Para um passo a passo completo, consulte o [guia de início rápido](/pt-BR/products/managed-postgres/quickstart).

<h2 id="connection-details">
  Obtenha os detalhes de conexão
</h2>

Clique em **Connect** na barra lateral esquerda do seu serviço. O modal exibe seu nome de usuário, senha, servidor e porta, além de strings de conexão prontas para uso.

Este guia usa duas conexões, pois o Prisma tem dois componentes que se comunicam com o banco de dados:

* **Sua aplicação (Prisma Client)** se conecta **via PgBouncer** na porta `6432`. O PgBouncer faz o pooling de conexões, permitindo que muitos processos da aplicação ou instâncias serverless compartilhem um pequeno número de backends do Postgres.
* **O Prisma CLI (Prisma Migrate)** se conecta **diretamente** na porta `5432`. Durante a execução, o Prisma Migrate adquire um bloqueio consultivo (advisory lock) em nível de sessão. No modo de pooling de transações do PgBouncer, esse bloqueio pode continuar retido em um backend do pool que passa a atender outros clientes, e as migrações seguintes ficam travadas aguardando sua liberação.

Na parte superior do modal, alterne entre **Directly** e **via PgBouncer** para ver cada porta. O servidor e as credenciais são os mesmos nas duas conexões; apenas a porta muda.

Com **via PgBouncer** selecionado, clique em **Download CA certificate**. Com **Directly** selecionado, ative antes a opção **Use SSL** para que o botão apareça. O arquivo se chama `<service-name>-ca-certificate.pem`. Ele também está disponível em **Settings → CA Certificate**. O certificado é exclusivo da sua instância e é usado para conectar com `sslmode=verify-full`, que verifica se você está se comunicando com o seu próprio servidor.

<h2 id="setup">
  Configure o projeto
</h2>

Crie um projeto TypeScript e instale a Prisma CLI, o Prisma Client, o adaptador de driver [node-postgres](https://node-postgres.com/) e o `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>
  Instale explicitamente `prisma@7` e `@prisma/client@7`. No momento em que este texto foi escrito, a tag `latest` do `prisma` no npm aponta para uma versão release candidate do Prisma 8, que usa uma configuração diferente da descrita neste guia.
</Note>

Crie um arquivo `tsconfig.json`:

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

<Tip>
  **Vai adicionar a um aplicativo existente?**

  Pule o `mkdir`, o `npm init` e o `tsconfig.json`. No seu projeto, execute `npm install tsx @types/pg prisma@7 --save-dev` e `npm install @prisma/client@7 @prisma/adapter-pg pg dotenv` e depois siga para [Inicializar o Prisma](#init).
</Tip>

<h2 id="init">
  Inicializar o Prisma
</h2>

<Steps>
  <Step title="Execute prisma init">
    ```bash theme={null}
    npx prisma init --datasource-provider postgresql --output ../generated/prisma
    ```

    Isso cria `prisma/schema.prisma` e o arquivo de configuração do Prisma `prisma7.config.ts`, adiciona um `DATABASE_URL` provisório ao `.env` e o cliente gerado ao `.gitignore` (criando esses arquivos, se necessário), além de adicionar as skills do Prisma para agentes de programação com IA. A partir da versão 7.10, o Prisma nomeia o arquivo de configuração como `prisma7.config.ts` para evitar conflito com o formato do Prisma 8.
  </Step>

  <Step title="Adicione o certificado da CA">
    Mova o certificado da CA que você baixou para a raiz do projeto e renomeie-o para `ca-certificate.pem`:

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

    Caminhos relativos de certificados são resolvidos a partir do diretório em que você executa os comandos. Por isso, execute todos os comandos deste guia a partir da raiz do projeto.
  </Step>
</Steps>

<h2 id="configure">
  Configure a conexão
</h2>

<Steps>
  <Step title="Crie um banco de dados">
    Crie um banco de dados para a aplicação. Substitua `<PASSWORD>` e o host pelos valores exibidos no modal **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="Defina as URLs de conexão">
    No arquivo `.env`, substitua o `DATABASE_URL` provisório adicionado pelo `prisma init` por estas duas URLs de conexão, ambas apontando para o banco de dados `guide_prisma`. Use a senha exibida no modal Connect:

    ```bash theme={null}
    # Prisma Client (sua aplicação): via PgBouncer, porta 6432
    DATABASE_URL="postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:6432/guide_prisma?sslmode=verify-full&sslrootcert=ca-certificate.pem"

    # Prisma CLI (migrations): conexão direta, porta 5432
    DIRECT_URL="postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/guide_prisma?sslmode=require&sslaccept=strict&sslcert=ca-certificate.pem"
    ```

    As duas URLs usam parâmetros de TLS diferentes porque são lidas por drivers diferentes:

    * **`DATABASE_URL`** é lida pelo node-postgres por meio do `@prisma/adapter-pg`. Ela aceita os parâmetros padrão `sslmode=verify-full&sslrootcert=...`, os mesmos exibidos no modal Connect.
    * **`DIRECT_URL`** é lida pelo motor de schema da Prisma CLI, que tem parâmetros próprios: `sslcert` é o caminho para o certificado da CA, e `sslaccept=strict` ativa a verificação do certificado e do hostname.

    <Warning>
      Não use `sslmode=verify-full&sslrootcert=...` na URL da Prisma CLI. O motor de schema ignora `sslrootcert` e, sem `sslaccept=strict`, simplesmente não verifica o certificado do servidor. Com isso, a conexão fica criptografada, mas não autenticada.
    </Warning>
  </Step>

  <Step title="Aponte a Prisma CLI para a conexão direta">
    Substitua o conteúdo de `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"),
      },
    });
    ```

    No Prisma 7, a URL definida no arquivo de configuração é usada apenas pela CLI. O Prisma Client obtém a conexão pelo adaptador de driver, que você configura em [Consulte o banco de dados](#query).
  </Step>
</Steps>

<h2 id="migrate">
  Defina o schema e execute a migração
</h2>

<Steps>
  <Step title="Adicione um model">
    Adicione um model `Todo` ao final de `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="Execute a migração">
    No Linux, execute o Prisma Migrate diretamente:

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

    No macOS, execute o mesmo comando em um contêiner Linux:

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

    <Warning>
      O ClickHouse Managed Postgres aceita apenas TLS 1.3. No macOS, o motor de schema da Prisma CLI usa a biblioteca TLS do sistema, que não consegue se conectar com essas configurações. A conexão falha com `P1011: Error opening a TLS connection: One or more parameters passed to a function were not valid` ou, se você remover `sslcert`, com `bad protocol version` ([prisma/orm#29600](https://github.com/prisma/orm/issues/29600)). Isso afeta apenas os comandos da CLI que se conectam ao banco de dados, como `prisma migrate` e `prisma db pull`. O Prisma Client não é afetado, pois se conecta por meio do node-postgres. Para contornar o problema, execute a CLI em um contêiner Linux ou no seu pipeline de CI baseado em Linux.
    </Warning>

    O Prisma cria a migração SQL em `prisma/migrations/` e a aplica:

    ```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="Gere o Prisma Client">
    ```bash theme={null}
    npx prisma generate
    ```

    O cliente é gerado em `generated/prisma`. Como esse comando não se conecta ao banco de dados, você pode executá-lo em qualquer plataforma.
  </Step>
</Steps>

<h2 id="query">
  Consultar o banco de dados
</h2>

<Steps>
  <Step title="Criar o Prisma Client">
    Crie `lib/prisma.ts`. O adaptador `PrismaPg` se conecta usando a `DATABASE_URL`, por meio do PgBouncer:

    ```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>
      **Nenhuma configuração do PgBouncer é necessária**

      O `@prisma/adapter-pg` envia cada consulta como um prepared statement sem nome e nunca executa `DEALLOCATE`, o que é compatível com o modo de pooling de transações do PgBouncer. Ele processa centenas de consultas distintas em execução simultânea nos backends do pool sem erros. O parâmetro de URL `pgbouncer=true`, usado em versões mais antigas do Prisma, não é necessário e não tem efeito com o adaptador de driver.
    </Tip>
  </Step>

  <Step title="Executar consultas CRUD">
    Crie `script.ts`:

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

    async function main() {
      // Criar
      const todo = await prisma.todo.create({
        data: { title: "Connect Prisma to ClickHouse Managed Postgres" },
      });
      console.log("Created:", todo);

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

      // Atualizar
      const updated = await prisma.todo.update({
        where: { id: todo.id },
        data: { done: true },
      });
      console.log("Updated:", updated);

      // Excluir
      await prisma.todo.delete({ where: { id: todo.id } });
      console.log("Deleted todo", todo.id);
    }

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

    Execute o script:

    ```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="Servir os dados via HTTP">
    Crie `server.ts`, um servidor HTTP mínimo que cria todos com `POST /todos` e os lista em qualquer requisição `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}`));
    ```

    Inicie o servidor:

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

    Em outro terminal, adicione dois todos:

    ```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"}'
    ```

    Abra [http://localhost:3000/todos](http://localhost:3000/todos) no navegador para visualizá-los. A resposta será semelhante a esta:

    ```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">
  Verifique no SQL Console
</h2>

No console do ClickHouse Cloud, abra o **SQL Console** do seu serviço, expanda o seu banco de dados e o schema `public` e selecione a tabela `Todo`. Você também verá a tabela `_prisma_migrations`, onde o Prisma Migrate registra as migrações aplicadas.

A tabela `Todo` contém as duas linhas que você adicionou pelo endpoint 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">
  Solução de problemas
</h2>

| Erro | Causa e correção |
| - | - |
| `P1011: Error opening a TLS connection: One or more parameters passed to a function were not valid` ou `bad protocol version` | A Prisma CLI está sendo executada no macOS. Execute-a em um contêiner Linux, conforme mostrado em [Executar a migração](#migrate). |
| `P1011: ... certificate verify failed` | A Prisma CLI não consegue verificar o servidor. Confira se `sslcert` em `DIRECT_URL` aponta para o certificado da CA da sua instância. |
| `P1011: ... cert file not found` | O caminho de `sslcert` em `DIRECT_URL` está incorreto. Execute a CLI a partir da raiz do projeto ou use um caminho absoluto. |
| `unable to verify the first certificate` | O Prisma Client não consegue verificar o servidor. Confira se `sslrootcert` em `DATABASE_URL` aponta para o certificado da CA da sua instância. |
| `ENOENT: no such file or directory` | O caminho de `sslrootcert` em `DATABASE_URL` está incorreto. Execute sua aplicação a partir da raiz do projeto ou use um caminho absoluto. |

<h2 id="next-steps">
  Próximos passos
</h2>

* [Conexão](/pt-BR/products/managed-postgres/connection): strings de conexão, PgBouncer e TLS
* [Configurações](/pt-BR/products/managed-postgres/settings): ajuste os parâmetros do Postgres e do PgBouncer
* [Réplicas de leitura](/pt-BR/products/managed-postgres/read-replicas): escale cargas de trabalho com uso intensivo de leitura
* [Desenvolvimento local](/pt-BR/products/managed-postgres/local-development): desenvolva com um Postgres local no Docker
* [Prisma Migrate em produção](https://www.prisma.io/docs/orm/prisma-migrate/workflows/development-and-production): use `prisma migrate deploy` no seu pipeline de CI
