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

> Permet d'exécuter des requêtes `SELECT` et `INSERT` sur des données stockées sur un serveur PostgreSQL distant.

# postgresql

Permet d'exécuter des requêtes `SELECT` et `INSERT` sur des données stockées sur un serveur PostgreSQL distant.

## Syntaxe

```sql theme={null}
postgresql({host:port, database, table, user, password[, schema, [, on_conflict]] | named_collection[, option=value [,..]]} [, SETTINGS name=value, ...])
```

## Arguments

| Argument | Description |
| - | - |
| `host:port` | Adresse du serveur PostgreSQL. |
| `database` | Nom de la base de données distante. |
| `table` | Nom de la table distante, ou une requête transmise à PostgreSQL telle quelle (voir [passer une requête au lieu d’un nom de table](#passing-a-query)). |
| `user` | Utilisateur PostgreSQL. |
| `password` | Mot de passe de l'utilisateur. |
| `schema` | Schéma de table autre que celui par défaut. Facultatif. |
| `on_conflict` | Stratégie de résolution des conflits. Exemple : `ON CONFLICT DO NOTHING`. Facultatif. |

Les arguments peuvent également être transmis à l'aide de [collections nommées](/fr/concepts/features/configuration/server-config/named-collections). Dans ce cas, `host` et `port` doivent être indiqués séparément. Cette approche est recommandée en production.

Les paramètres TLS/SSL sont transmis à `libpq` et peuvent être fournis sous forme de clés de collection nommée ou d’arguments clé-valeur ajoutés à la fin : `sslmode` (`disable`, `allow`, `prefer`, `require`, `verify-ca` ou `verify-full` ; s’il n’est pas défini, la valeur par défaut `prefer` de `libpq` s’applique), ainsi que les certificats et la clé, sous l’une de deux formes. `sslrootcert` (certificat d’AC ou valeur spéciale `system`), `sslcert` (certificat client) et `sslkey` (clé privée du client) sont des chemins vers des fichiers locaux au serveur et ne peuvent être spécifiés que dans une collection nommée définie dans le fichier de configuration du serveur. `sslrootcert_pem`, `sslcert_pem` et `sslkey_pem` acceptent à la place le contenu littéral du fichier correspondant — par exemple, `postgresql('host:port', 'database', 'table', 'user', 'password', sslmode = 'verify-full', sslrootcert_pem = '...')` — et sont masqués dans les journaux et les requêtes `SHOW`, comme un mot de passe.

## Valeur renvoyée

Un objet de type table avec les mêmes colonnes que la table PostgreSQL d'origine.

<Note>
  Dans la requête `INSERT`, pour distinguer la fonction de table `postgresql(...)` d'un nom de table accompagné d'une liste de noms de colonnes, vous devez utiliser les mots-clés `FUNCTION` ou `TABLE FUNCTION`. Voir les exemples ci-dessous.
</Note>

## Paramètres

Le pool de connexions utilisé par la fonction de table `postgresql` (ainsi que par le moteur de table [`PostgreSQL`](/fr/reference/engines/table-engines/integrations/postgresql)) peut être configuré à l’aide d’une clause `SETTINGS` en fin d’instruction. Lorsqu’un paramètre n’est pas spécifié, il prend par défaut la valeur du paramètre `postgresql_*` correspondant au niveau de la requête. Consultez la section [Paramètres](/fr/reference/engines/table-engines/integrations/postgresql#settings) du moteur de table pour obtenir la liste complète des paramètres `postgresql_connection_pool_*` et `postgresql_connection_attempt_timeout`, ainsi que leurs valeurs par défaut.

Exemple :

```sql theme={null}
SELECT * FROM postgresql('localhost:5432', 'test', 'test', 'postgresql_user', 'password', SETTINGS postgresql_connection_pool_size = 32);
```

## Détails d’implémentation

Les requêtes `SELECT` côté PostgreSQL s’exécutent sous la forme de `COPY (SELECT ...) TO STDOUT` à l’intérieur d’une transaction PostgreSQL en lecture seule, avec un commit après chaque requête `SELECT`.

Les clauses `WHERE` simples, telles que `=`, `!=`, `>`, `>=`, `<`, `<=` et `IN`, sont exécutées sur le serveur PostgreSQL.

Toutes les jointures, agrégations, opérations de tri, conditions `IN [ array ]` et la contrainte d’échantillonnage `LIMIT` sont exécutées dans ClickHouse, uniquement une fois la requête PostgreSQL terminée.

## Utilisation d’une requête à la place d’un nom de table

Au lieu d’un nom de table, le troisième argument peut être une requête `SELECT` transmise telle quelle à PostgreSQL. La structure de la table résultante est inférée à partir du résultat de la requête. La requête peut être écrite soit comme une sous-requête, soit encapsulée dans la fonction `query` :

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

Cela est utile pour déléguer à PostgreSQL les jointures, les agrégations ou tout autre traitement. Une telle table est en lecture seule : les requêtes `INSERT` n’y sont pas autorisées. La même syntaxe est prise en charge par le moteur de table [`PostgreSQL`](/fr/reference/engines/table-engines/integrations/postgresql).

<Note>
  La forme de sous-requête `(SELECT ...)` est analysée par ClickHouse puis re-sérialisée dans le dialecte PostgreSQL (quotage des identifiants PostgreSQL et échappement des littéraux de chaîne) avant d’être envoyée au serveur. Elle doit donc être valide en ClickHouse SQL. Pour transmettre une syntaxe spécifique à PostgreSQL que ClickHouse n’analyse pas, utilisez la forme `query('...')`, dont le texte est envoyé tel quel à PostgreSQL.

  Toute clause externe `WHERE`, `LIMIT`, agrégation, etc. de la requête ClickHouse englobante n’est **pas** déléguée à la requête transmise — elle est appliquée dans ClickHouse après récupération du résultat complet de la requête. Pour restreindre les données lues depuis PostgreSQL, placez le filtre dans la requête transmise. Avec [`external_table_strict_query = 1`](/fr/reference/settings/session-settings/external-table#external_table_strict_query), un filtre externe portant sur les colonnes de la fonction de table est rejeté avec une exception au lieu d’être appliqué localement, car il ne peut pas être injecté dans la requête transmise. La vérification couvre le prédicat `WHERE` de premier niveau ainsi que chaque conjonction d’un `AND` de premier niveau. Un `PREWHERE` sur les colonnes de cette table ne relève pas de ce paramètre : ce moteur de table ne prend pas en charge `PREWHERE`, et une telle requête est rejetée avec `ILLEGAL_PREWHERE` indépendamment du paramètre. La vérification n’a lieu que là où un filtre pourrait effectivement être délégué : lorsque cette table est la seule table de la requête, de part et d’autre d’un `INNER JOIN`, ou du côté préservé d’une jointure externe (le côté gauche d’un `LEFT JOIN`, le côté droit d’un `RIGHT JOIN`). Du côté non préservé d’un `LEFT`/`RIGHT JOIN` et de part et d’autre d’un `FULL JOIN`, rien n’est délégué et rien n’est vérifié : un filtre sur les colonnes de cette table est donc appliqué localement après la jointure, même en mode strict. Là où la vérification s’applique, un prédicat qui référence d’autres tables jointes dans la requête englobante n’est pas délégué et est exclu de la vérification, qu’il référence uniquement le côté joint ou qu’il le mélange avec cette table dans une même expression non-`AND` (par exemple un `OR`) ; un tel prédicat conserve son point d’évaluation habituel dans ClickHouse (`WHERE` après la jointure, `PREWHERE` avant) et n’est pas rejeté.
</Note>

Les requêtes `INSERT` côté PostgreSQL s’exécutent sous la forme de `COPY "table_name" (field1, field2, ... fieldN) FROM STDIN` à l’intérieur d’une transaction PostgreSQL avec commit automatique après chaque instruction `INSERT`.

Les types Array de PostgreSQL sont convertis en tableaux ClickHouse.

<Note>
  Attention : dans PostgreSQL, une colonne de type tableau comme Integer\[] peut contenir des tableaux de dimensions différentes selon les lignes, mais dans ClickHouse, seuls des tableaux multidimensionnels de même dimension sont autorisés dans toutes les lignes.
</Note>

Prend en charge plusieurs répliques, qui doivent être séparées par `|`. Par exemple :

```sql theme={null}
SELECT name FROM postgresql(`postgres{1|2|3}:5432`, 'postgres_database', 'postgres_table', 'user', 'password');
```

ou

```sql theme={null}
SELECT name FROM postgresql(`postgres1:5431|postgres2:5432`, 'postgres_database', 'postgres_table', 'user', 'password');
```

Prend en charge la priorité des répliques pour la source de dictionnaire PostgreSQL. Plus le nombre dans la map est élevé, plus la priorité est faible. La priorité la plus élevée est `0`.

## Exemples

Table dans PostgreSQL :

```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)
```

Sélection de données dans ClickHouse à l’aide d’arguments simples :

```sql theme={null}
SELECT * FROM postgresql('localhost:5432', 'test', 'test', 'postgresql_user', 'password') WHERE str IN ('test');
```

Ou en utilisant des [collections nommées](/fr/concepts/features/configuration/server-config/named-collections) :

```sql theme={null}
CREATE NAMED COLLECTION mypg AS
        host = 'localhost',
        port = 5432,
        database = 'test',
        user = 'postgresql_user',
        password = 'password';
SELECT * FROM postgresql(mypg, table='test') WHERE str IN ('test');
```

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

Insertion :

```sql theme={null}
INSERT INTO TABLE FUNCTION postgresql('localhost:5432', 'test', 'test', 'postgrsql_user', 'password') (int_id, float) VALUES (2, 3);
SELECT * FROM postgresql('localhost:5432', 'test', 'test', 'postgresql_user', 'password');
```

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

Utiliser un schéma non par défaut :

```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');
```

## Voir aussi

* [Le moteur de table PostgreSQL](/fr/reference/engines/table-engines/integrations/postgresql)
* [Utiliser PostgreSQL comme source pour un dictionnaire](/fr/reference/statements/create/dictionary/sources/postgresql)

### Répliquer ou migrer des données Postgres avec PeerDB

> En plus des fonctions de table, vous pouvez également utiliser [PeerDB](https://docs.peerdb.io/introduction) de ClickHouse pour mettre en place un pipeline de données continu de Postgres vers ClickHouse. PeerDB est un outil spécialement conçu pour répliquer des données de Postgres vers ClickHouse à l’aide de la capture de données modifiées (CDC).
