> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/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](/docs/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],
    name2 type2 [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
) ENGINE = PostgreSQL({host:port, database, table, user, password[, schema, [, on_conflict]] | named_collection[, option=value [,..]]})
SETTINGS
    [ postgresql_connection_pool_size=16, ]
    [ postgresql_connection_pool_wait_timeout=5000, ]
    [ postgresql_connection_pool_retries=2, ]
    [ postgresql_connection_pool_auto_close_connection=false, ]
    [ postgresql_connection_attempt_timeout=2 ]
;
```

Veja uma descrição detalhada da consulta [CREATE TABLE](/docs/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](/docs/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](/docs/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 ou uma consulta passada ao PostgreSQL como está (veja [Passando uma consulta em vez de um nome de tabela](#passing-a-query)).
* `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](/docs/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="settings">
  ## Configurações
</div>

O pool de conexões usado pelo motor de tabela `PostgreSQL` (e pela função de tabela [`postgresql`](/docs/pt-BR/reference/functions/table-functions/postgresql)) pode ser configurado para cada tabela com uma cláusula `SETTINGS`. Quando uma configuração não é especificada, o valor padrão é o da configuração `postgresql_*` correspondente no nível da consulta.

<div id="postgresql-connection-pool-size">
  ### `postgresql_connection_pool_size`
</div>

Tamanho do pool de conexões (se todas as conexões estiverem em uso, a consulta aguardará até que alguma delas seja liberada). Deve ser maior que zero.

Valor padrão: `16`.

<div id="postgresql-connection-pool-wait-timeout">
  ### `postgresql_connection_pool_wait_timeout`
</div>

Tempo limite, em milissegundos, para push/pop no pool de conexões quando o pool está vazio. `0` significa que a operação bloqueia quando o pool está vazio.

Valor padrão: `5000`.

<div id="postgresql-connection-pool-retries">
  ### `postgresql_connection_pool_retries`
</div>

Número de tentativas de nova tentativa ao obter/devolver conexões do pool.

Valor padrão: `2`.

<div id="postgresql-connection-pool-auto-close-connection">
  ### `postgresql_connection_pool_auto_close_connection`
</div>

Feche a conexão antes de devolvê-la ao pool.

Valor padrão: `false`.

<div id="postgresql-connection-attempt-timeout">
  ### `postgresql_connection_attempt_timeout`
</div>

Tempo limite de conexão, em segundos, para uma única tentativa de conexão ao endpoint do PostgreSQL. O valor é passado como parâmetro `connect_timeout` na URL de conexão.

Valor padrão: `2`.

Exemplo:

```sql theme={null}
CREATE TABLE pg_table
(
    `float_nullable` Nullable(Float32),
    `str` String,
    `int_id` Int32
)
ENGINE = PostgreSQL('localhost:5432', 'public', 'test', 'postgres_user', 'postgres_password')
SETTINGS postgresql_connection_pool_size = 32, postgresql_connection_pool_auto_close_connection = 1;
```

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

<div id="passing-a-query">
  ## Passando uma consulta em vez de um nome de tabela
</div>

Em vez de um nome de tabela, o argumento `table` pode ser uma consulta `SELECT` passada ao PostgreSQL como está. A estrutura da tabela é inferida a partir do resultado da consulta. A consulta pode ser escrita como uma subconsulta ou encapsulada na função `query`:

```sql theme={null}
CREATE TABLE pg_table ENGINE = PostgreSQL('localhost:5432', 'test', (SELECT a, b FROM t1 JOIN t2 USING (id) WHERE a > 0), 'user', 'password');
CREATE TABLE pg_table ENGINE = PostgreSQL('localhost:5432', 'test', query('SELECT a, b FROM t1 JOIN t2 USING (id) WHERE a > 0'), 'user', 'password');
```

Isso é útil para delegar junções, agregações ou qualquer outro processamento ao PostgreSQL. Essa tabela é somente leitura: `INSERT` nela não é permitido. A mesma sintaxe também é compatível com a função de tabela [`postgresql`](/docs/pt-BR/reference/functions/table-functions/postgresql).

<Note>
  A forma de subconsulta `(SELECT ...)` é analisada pelo ClickHouse e reserializada no dialeto PostgreSQL (aspas de identificadores do PostgreSQL e escapamento de literais de string) antes de ser enviada ao servidor. Portanto, ela deve ser um ClickHouse SQL válido. Para passar sintaxe específica do PostgreSQL que o ClickHouse não analisa, use a forma `query('...')`, cujo texto é enviado ao PostgreSQL literalmente.

  Qualquer `WHERE`, `LIMIT`, agregação etc. externo da consulta ClickHouse circundante **não** é delegado à consulta passada — ele é aplicado no ClickHouse após a obtenção do resultado completo da consulta. Para restringir os dados lidos do PostgreSQL, coloque o filtro dentro da consulta passada. Com [`external_table_strict_query = 1`](/docs/pt-BR/reference/settings/session-settings#external_table_strict_query), um filtro externo que não pode ser delegado é rejeitado com uma exceção em vez de ser aplicado localmente.
</Note>

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](/docs/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](/docs/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', 'postgres_user', 'postgres_password')
WHERE int_id > (SELECT max(int_id) FROM default.postgresql_copy);
```

<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`](/docs/pt-BR/reference/functions/table-functions/postgresql)
* [Usando PostgreSQL como fonte de um dicionário](/docs/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)
