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

> O motor PostgreSQL permite consultas `SELECT` e `INSERT` em dados armazenados em um servidor PostgreSQL remoto.

# Motor de tabela PostgreSQL

O motor PostgreSQL permite consultas `SELECT` e `INSERT` em dados armazenados em um servidor PostgreSQL remoto.

<Note>
  Atualmente, apenas as versões 12 ou superiores do PostgreSQL são compatíveis com o motor de tabela.
</Note>

<Tip>
  Conheça nosso serviço [Managed Postgres](/pt-BR/products/managed-postgres/overview). Com armazenamento NVMe fisicamente no mesmo local que a computação, ele oferece desempenho até 10x mais rápido para cargas de trabalho limitadas por disco em comparação com alternativas que usam armazenamento conectado à rede, como o EBS, e permite replicar seus dados do Postgres para o ClickHouse usando o conector Postgres CDC no ClickPipes.
</Tip>

<div id="creating-a-table">
  ## Criando uma tabela
</div>

```sql theme={null}
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 type1 [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1],
    name2 type2 [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2],
    ...
) ENGINE = PostgreSQL({host:port, database, table, user, password[, schema, [, on_conflict]] | named_collection[, option=value [,..]]})
```

Veja uma descrição detalhada da consulta [CREATE TABLE](/pt-BR/reference/statements/create/table).

A estrutura da tabela pode ser diferente da estrutura da tabela PostgreSQL original:

* Os nomes das colunas devem ser os mesmos da tabela PostgreSQL original, mas você pode usar apenas algumas delas e em qualquer ordem.
* Os tipos das colunas podem ser diferentes dos da tabela PostgreSQL original. O ClickHouse tenta [converter](/pt-BR/reference/engines/database-engines/postgresql#data_types-support) os valores para os tipos de dados do ClickHouse.
* A configuração [external\_table\_functions\_use\_nulls](/pt-BR/reference/settings/session-settings#external_table_functions_use_nulls) define como tratar colunas Nullable. Valor padrão: 1. Se for 0, a função de tabela não cria colunas Nullable e insere valores padrão em vez de valores nulos. Isso também se aplica a valores NULL dentro de arrays.

**Parâmetros do motor**

* `host:port` — Endereço do servidor PostgreSQL.
* `database` — Nome do banco de dados remoto.
* `table` — Nome da tabela remota.
* `user` — Usuário do PostgreSQL.
* `password` — Senha do usuário.
* `schema` — Esquema de tabela não padrão. Opcional.
* `on_conflict` — Estratégia de resolução de conflitos. Exemplo: `ON CONFLICT DO NOTHING`. Opcional. Observação: adicionar esta opção tornará a inserção menos eficiente.

[Coleções nomeadas](/pt-BR/concepts/features/configuration/server-config/named-collections) (disponíveis desde a versão 21.11) são recomendadas para ambientes de produção. Aqui está um exemplo:

```xml theme={null}
<named_collections>
    <postgres_creds>
        <host>localhost</host>
        <port>5432</port>
        <user>postgres</user>
        <password>****</password>
        <schema>schema1</schema>
    </postgres_creds>
</named_collections>
```

Alguns parâmetros podem ser substituídos por argumentos de chave-valor:

```sql theme={null}
SELECT * FROM postgresql(postgres_creds, table='table1');
```

<div id="implementation-details">
  ## Detalhes de implementação
</div>

As consultas `SELECT` no PostgreSQL são executadas como `COPY (SELECT ...) TO STDOUT` dentro de uma transação PostgreSQL somente leitura, com commit após cada consulta `SELECT`.

Cláusulas `WHERE` simples, como `=`, `!=`, `>`, `>=`, `<`, `<=` e `IN`, são executadas no servidor PostgreSQL.

Todas as junções, agregações, ordenações, condições `IN [ array ]` e a restrição de amostragem `LIMIT` são executadas no ClickHouse somente após a conclusão da consulta ao PostgreSQL.

As consultas `INSERT` no PostgreSQL são executadas como `COPY "table_name" (field1, field2, ... fieldN) FROM STDIN` dentro de uma transação PostgreSQL, com commit automático após cada instrução `INSERT`.

Os tipos `Array` do PostgreSQL são convertidos em arrays do ClickHouse.

<Note>
  Atenção: no PostgreSQL, um dado de array, criado como `type_name[]`, pode conter arrays multidimensionais com números diferentes de dimensões em diferentes linhas da mesma coluna da tabela. Já no ClickHouse, só é permitido ter arrays multidimensionais com a mesma quantidade de dimensões em todas as linhas da mesma coluna da tabela.
</Note>

Há suporte para várias réplicas, que devem ser listadas com `|`. Por exemplo:

```sql theme={null}
CREATE TABLE test_replicas (id UInt32, name String) ENGINE = PostgreSQL(`postgres{2|3|4}:5432`, 'clickhouse', 'test_replicas', 'postgres', 'mysecretpassword');
```

Há suporte a prioridade de réplicas para a fonte de dicionário do PostgreSQL. Quanto maior o número no map, menor a prioridade. A prioridade mais alta é `0`.

No exemplo abaixo, a réplica `example01-1` tem a maior prioridade:

```xml theme={null}
<postgresql>
    <port>5432</port>
    <user>clickhouse</user>
    <password>qwerty</password>
    <replica>
        <host>example01-1</host>
        <priority>1</priority>
    </replica>
    <replica>
        <host>example01-2</host>
        <priority>2</priority>
    </replica>
    <db>db_name</db>
    <table>table_name</table>
    <where>id=10</where>
    <invalidate_query>SQL_QUERY</invalidate_query>
</postgresql>
</source>
```

<div id="usage-example">
  ## Exemplo de uso
</div>

<div id="table-in-postgresql">
  ### Tabela no PostgreSQL
</div>

```text theme={null}
postgres=# CREATE TABLE "public"."test" (
"int_id" SERIAL,
"int_nullable" INT NULL DEFAULT NULL,
"float" FLOAT NOT NULL,
"str" VARCHAR(100) NOT NULL DEFAULT '',
"float_nullable" FLOAT NULL DEFAULT NULL,
PRIMARY KEY (int_id));

CREATE TABLE

postgres=# INSERT INTO test (int_id, str, "float") VALUES (1,'test',2);
INSERT 0 1

postgresql> SELECT * FROM test;
  int_id | int_nullable | float | str  | float_nullable
 --------+--------------+-------+------+----------------
       1 |              |     2 | test |
 (1 row)
```

<div id="creating-table-in-clickhouse-and-connecting-to--postgresql-table-created-above">
  ### Criando uma tabela no ClickHouse e conectando-a à tabela do PostgreSQL criada acima
</div>

Este exemplo usa o [PostgreSQL motor de tabela](/pt-BR/reference/engines/table-engines/integrations/postgresql) para conectar a tabela do ClickHouse à tabela do PostgreSQL e usar instruções SELECT e INSERT no banco de dados PostgreSQL:

```sql theme={null}
CREATE TABLE default.postgresql_table
(
    `float_nullable` Nullable(Float32),
    `str` String,
    `int_id` Int32
)
ENGINE = PostgreSQL('localhost:5432', 'public', 'test', 'postgres_user', 'postgres_password');
```

<div id="inserting-initial-data-from-postgresql-table-into-clickhouse-table-using-a-select-query">
  ### Inserindo dados iniciais de uma tabela do PostgreSQL em uma tabela do ClickHouse usando uma consulta SELECT
</div>

A [função de tabela postgresql](/pt-BR/reference/functions/table-functions/postgresql) copia os dados do PostgreSQL para o ClickHouse. Isso costuma ser usado para melhorar o desempenho das consultas sobre esses dados, executando consultas ou análises no ClickHouse em vez de no PostgreSQL, e também pode ser usado para migrar dados do PostgreSQL para o ClickHouse. Como vamos copiar os dados do PostgreSQL para o ClickHouse, usaremos um motor de tabela MergeTree no ClickHouse e o chamaremos de postgresql\_copy:

```sql theme={null}
CREATE TABLE default.postgresql_copy
(
    `float_nullable` Nullable(Float32),
    `str` String,
    `int_id` Int32
)
ENGINE = MergeTree
ORDER BY (int_id);
```

```sql theme={null}
INSERT INTO default.postgresql_copy
SELECT * FROM postgresql('localhost:5432', 'public', 'test', 'postgres_user', 'postgres_password');
```

<div id="inserting-incremental-data-from-postgresql-table-into-clickhouse-table">
  ### Inserindo dados incrementais da tabela PostgreSQL na tabela do ClickHouse
</div>

Se depois do insert inicial você quiser realizar uma sincronização contínua entre a tabela PostgreSQL e a tabela do ClickHouse, poderá usar uma cláusula WHERE no ClickHouse para inserir apenas os dados adicionados ao PostgreSQL com base em um timestamp ou em um ID de sequência exclusivo.

Isso exigirá acompanhar o ID máximo ou o timestamp adicionado anteriormente, como no exemplo a seguir:

```sql theme={null}
SELECT max(`int_id`) AS maxIntID FROM default.postgresql_copy;
```

Em seguida, inserindo valores da tabela do PostgreSQL maiores que o máximo

```sql theme={null}
INSERT INTO default.postgresql_copy
SELECT * FROM postgresql('localhost:5432', 'public', 'test', 'postges_user', 'postgres_password');
WHERE int_id > maxIntID;
```

<div id="selecting-data-from-the-resulting-clickhouse-table">
  ### Selecionando dados da tabela resultante no ClickHouse
</div>

```sql theme={null}
SELECT * FROM postgresql_copy WHERE str IN ('test');
```

```text theme={null}
┌─float_nullable─┬─str──┬─int_id─┐
│           ᴺᵁᴸᴸ │ test │      1 │
└────────────────┴──────┴────────┘
```

<div id="using-non-default-schema">
  ### Usando um esquema diferente do padrão
</div>

```text theme={null}
postgres=# CREATE SCHEMA "nice.schema";

postgres=# CREATE TABLE "nice.schema"."nice.table" (a integer);

postgres=# INSERT INTO "nice.schema"."nice.table" SELECT i FROM generate_series(0, 99) as t(i)
```

```sql theme={null}
CREATE TABLE pg_table_schema_with_dots (a UInt32)
        ENGINE PostgreSQL('localhost:5432', 'clickhouse', 'nice.table', 'postgrsql_user', 'password', 'nice.schema');
```

**Veja também**

* [A função de tabela `postgresql`](/pt-BR/reference/functions/table-functions/postgresql)
* [Usando PostgreSQL como fonte de um dicionário](/pt-BR/reference/statements/create/dictionary/sources/postgresql)

<div id="related-content">
  ## Conteúdo relacionado
</div>

* Blog: [ClickHouse and PostgreSQL - uma combinação perfeita para o universo dos dados - parte 1](https://clickhouse.com/blog/migrating-data-between-clickhouse-postgres)
* Blog: [ClickHouse and PostgreSQL - uma combinação perfeita para o universo dos dados - parte 2](https://clickhouse.com/blog/migrating-data-between-clickhouse-postgres-part-2)
