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

# Démarrage rapide pour Managed Postgres

> Découvrez les performances NVMe de Postgres et ajoutez de l’analytique en temps réel grâce à l’intégration native à ClickHouse

Cette page explique comment provisionner ClickHouse Managed Postgres, charger des données, les répliquer vers ClickHouse et exécuter des requêtes sur celles-ci, le tout depuis la ligne de commande avec le [ClickHouse CLI](/docs/fr/products/cloud/features/cli) (`clickhousectl`) et `psql`. Les commandes s’exécutent en mode non interactif ; `clickhousectl` renvoie du JSON avec `--json`.

<div id="prerequisites">
  ## Prérequis
</div>

Installez la ClickHouse CLI :

```bash theme={null}
curl https://clickhouse.com/cli | sh
```

Vous avez également besoin de `psql` (outils du client PostgreSQL ; sous macOS, `brew install libpq`) et de `jq`.

Les opérations en écriture (create, delete) nécessitent une [authentification par clé API](/docs/fr/products/cloud/features/admin-features/api/openapi) ; la connexion OAuth est en lecture seule :

```bash theme={null}
clickhousectl cloud auth login --api-key <YOUR_KEY> --api-secret <YOUR_SECRET>
```

Vous pouvez également définir les variables d’environnement `CLICKHOUSE_CLOUD_API_KEY` et `CLICKHOUSE_CLOUD_API_SECRET`. Vérifiez avec `clickhousectl cloud auth status` ; vous devriez voir une entrée avec la portée `read/write`.

<div id="part-1-create-and-load">
  ## Partie 1 : Créer Postgres et charger les données
</div>

<div id="create-postgres-service">
  ### Créer un service Postgres
</div>

Créez le service et enregistrez la réponse ; le mot de passe n’est affiché qu’une seule fois :

```bash theme={null}
clickhousectl cloud postgres create \
  --name quickstart-pg \
  --region us-east-1 \
  --size c6gd.large \
  --pg-version 18 \
  --json > pg.json
```

La réponse inclut l’ID du service, le nom d’hôte et une chaîne de connexion prête à l’emploi :

```json theme={null}
{
  "id": "3b5a3112-bf02-82d0-bd02-fbe67d5caa7a",
  "name": "quickstart-pg",
  "provider": "aws",
  "region": "us-east-1",
  "postgresVersion": "18",
  "size": "c6gd.large",
  "storageSize": 118,
  "haType": "none",
  "state": "creating",
  "createdAt": "2026-07-22T13:21:22Z",
  "hostname": "quickstart-pg-c1406b50.pg7dd324nz0a1qm1fqskxbjn7m.c0.us-east-1.aws.pg.clickhouse.cloud",
  "username": "postgres",
  "password": "vV6cfEr2p_-TzkCDrZOx",
  "connectionString": "postgres://postgres:vV6cfEr2p_-TzkCDrZOx@quickstart-pg-c1406b50.pg7dd324nz0a1qm1fqskxbjn7m.c0.us-east-1.aws.pg.clickhouse.cloud:5432/postgres?channel_binding=require",
  "isPrimary": true,
  "tags": []
}
```

Extrayez les éléments nécessaires pour la suite de ce guide :

```bash theme={null}
PG_ID=$(jq -r .id pg.json)
PG_URL=$(jq -r .connectionString pg.json)
```

Si le mot de passe est perdu, générez-en un nouveau avec `clickhousectl cloud postgres reset-password $PG_ID --generate`.

<div id="wait-for-provisioning">
  ### Attendez que le service soit provisionné
</div>

Le provisionnement prend quelques minutes. Vérifiez régulièrement jusqu’à ce que l’état soit `running` :

```bash theme={null}
while [ "$(clickhousectl cloud postgres get "$PG_ID" --json | jq -r .state)" != "running" ]; do
  sleep 15
done
```

<div id="load-sample-data">
  ### Charger des données d’exemple
</div>

Créez deux tables, puis insérez 1 million d’événements avec `psql` :

```bash theme={null}
psql "$PG_URL" <<'SQL'
\timing
CREATE TABLE events (
   event_id SERIAL PRIMARY KEY,
   event_name VARCHAR(255) NOT NULL,
   event_type VARCHAR(100),
   event_timestamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
   event_data JSONB,
   user_id INT,
   user_ip INET,
   is_active BOOLEAN DEFAULT TRUE,
   created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
   updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE users (
   user_id SERIAL PRIMARY KEY,
   name VARCHAR(100),
   country VARCHAR(50),
   platform VARCHAR(50)
);

INSERT INTO events (event_name, event_type, event_timestamp, event_data, user_id, user_ip)
SELECT
   'Event ' || gs::text AS event_name,
   CASE
       WHEN random() < 0.5 THEN 'click'
       WHEN random() < 0.75 THEN 'view'
       WHEN random() < 0.9 THEN 'purchase'
       WHEN random() < 0.98 THEN 'signup'
       ELSE 'logout'
   END AS event_type,
   NOW() - INTERVAL '1 day' * (gs % 365) AS event_timestamp,
   jsonb_build_object('key', 'value' || gs::text, 'additional_info', 'info_' || (gs % 100)::text) AS event_data,
   GREATEST(1, LEAST(1000, FLOOR(POWER(random(), 2) * 1000) + 1)) AS user_id,
   ('192.168.1.' || ((gs % 254) + 1))::inet AS user_ip
FROM
   generate_series(1, 1000000) gs;

INSERT INTO users (name, country, platform)
SELECT
    first_names[first_idx] || ' ' || last_names[last_idx] AS name,
    CASE
        WHEN random() < 0.25 THEN 'India'
        WHEN random() < 0.5 THEN 'USA'
        WHEN random() < 0.7 THEN 'Germany'
        WHEN random() < 0.85 THEN 'China'
        ELSE 'Other'
    END AS country,
    CASE
        WHEN random() < 0.2 THEN 'iOS'
        WHEN random() < 0.4 THEN 'Android'
        WHEN random() < 0.6 THEN 'Web'
        WHEN random() < 0.75 THEN 'Windows'
        WHEN random() < 0.9 THEN 'MacOS'
        ELSE 'Linux'
    END AS platform
FROM
    generate_series(1, 1000) AS seq
    CROSS JOIN LATERAL (
        SELECT
            array['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank', 'Grace', 'Hank', 'Ivy', 'Jack', 'Liam', 'Olivia', 'Noah', 'Emma', 'Sophia', 'Benjamin', 'Isabella', 'Lucas', 'Mia', 'Amelia', 'Aarav', 'Riya', 'Arjun', 'Ananya', 'Wei', 'Li', 'Huan', 'Mei', 'Hans', 'Klaus', 'Greta', 'Sofia'] AS first_names,
            array['Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Garcia', 'Miller', 'Davis', 'Martinez', 'Taylor', 'Anderson', 'Thomas', 'Jackson', 'White', 'Harris', 'Martin', 'Thompson', 'Moore', 'Lee', 'Perez', 'Sharma', 'Patel', 'Gupta', 'Reddy', 'Zhang', 'Wang', 'Chen', 'Liu', 'Schmidt', 'Müller', 'Weber', 'Fischer'] AS last_names,
            1 + (seq % 32) AS first_idx,
            1 + ((seq / 32)::int % 32) AS last_idx
    ) AS names;
SQL
```

```text theme={null}
Timing is on.
CREATE TABLE
Time: 86.029 ms
CREATE TABLE
Time: 80.962 ms
INSERT 0 1000000
Time: 7120.357 ms (00:07.120)
INSERT 0 1000
Time: 84.807 ms
```

L’insertion de 1 M de lignes s’effectue en environ 7 secondes sur `c6gd.large` (la plus petite taille), grâce au stockage NVMe. Vérifiez-le avec une requête ; le nombre de lignes varie d’une exécution à l’autre, car les données sont générées avec `random()` :

```bash theme={null}
psql "$PG_URL" -c "SELECT event_type, COUNT(*) FROM events GROUP BY event_type ORDER BY 2 DESC;"
```

<div id="part-2-replicate">
  ## Partie 2 : Répliquer dans ClickHouse
</div>

<div id="create-clickhouse-service">
  ### Créer un service ClickHouse
</div>

Créez un service dans la même région et enregistrez la réponse ; le mot de passe n’apparaît que dans la réponse de création :

```bash theme={null}
clickhousectl cloud service create \
  --name quickstart-ch \
  --region us-east-1 \
  --json > ch.json

CH_ID=$(jq -r .service.id ch.json)
CH_PASSWORD=$(jq -r .password ch.json)
```

Attendez qu’il soit actif ; le ClickPipe nécessite une destination active :

```bash theme={null}
while [ "$(clickhousectl cloud service get "$CH_ID" --json | jq -r .state)" != "running" ]; do
  sleep 15
done
```

Pour utiliser plutôt un service existant, définissez `CH_ID` à partir de `clickhousectl cloud service list` et `CH_PASSWORD` sur le mot de passe de l’utilisateur `default`, requis à l’étape `pg_clickhouse`.

<div id="replicate-to-clickhouse">
  ### Répliquer les tables vers ClickHouse
</div>

Créez un Postgres CDC ClickPipe sur le service ClickHouse, en pointant vers le nom d’hôte de Managed Postgres. Le pipe copie les lignes existantes, puis maintient ClickHouse synchronisé avec les changements ultérieurs :

```bash theme={null}
PG_HOST=$(jq -r .hostname pg.json)
PG_PASSWORD=$(jq -r .password pg.json)

clickhousectl cloud clickpipe create postgres "$CH_ID" \
  --name quickstart-sync \
  --host "$PG_HOST" \
  --pg-database postgres \
  --username postgres \
  --password "$PG_PASSWORD" \
  --table-mapping public.events:public_events \
  --table-mapping public.users:public_users \
  --json > pipe.json

PIPE_ID=$(jq -r .id pipe.json)
```

Remarques :

* Les tables répliquées sont créées dans la base de données `default` du service ClickHouse, selon les cibles de `--table-mapping`
* La publication et le slot de réplication sont créés automatiquement, la publication étant limitée aux tables mappées ; passez `--publication-name` pour utiliser celle que vous gérez vous-même
* Utilisez directement le nom d’hôte de Postgres ; la réplication n'est pas prise en charge via PgBouncer

<div id="wait-for-pipe">
  ### Attendez que le pipe passe à l’état `Running`
</div>

Le pipe passe par `Provisioning`, `Setup` et (pour les tables plus volumineuses) `Snapshot` avant de passer à l’état `Running`, ce qui prend environ 4 minutes pour le premier pipe sur un service. `Failed` et `InternalError` sont des états terminaux :

```bash theme={null}
while :; do
  STATE=$(clickhousectl cloud clickpipe get "$CH_ID" "$PIPE_ID" --json | jq -r .state)
  case "$STATE" in
    Running) break ;;
    Failed|InternalError) echo "ClickPipe entered terminal state: $STATE" >&2; exit 1 ;;
  esac
  sleep 15
done
```

<div id="query-clickhouse">
  ### Interroger les données répliquées dans ClickHouse
</div>

Exécutez des requêtes SQL sur le service ClickHouse directement depuis la CLI. Le premier appel crée automatiquement un endpoint Query API et une clé API limitée à ce service :

```bash theme={null}
clickhousectl cloud service query --id "$CH_ID" \
  --query "SELECT count() FROM public_events"
```

```text theme={null}
Provisioning Query API endpoint + key for service 'quickstart-ch'...
1000000
```

Les nouvelles écritures dans Postgres sont répliquées en continu. Insérez une ligne, puis interrogez régulièrement jusqu’à ce que le nombre atteigne 1 000 001 (généralement en moins d’une minute) :

```bash theme={null}
psql "$PG_URL" -c "INSERT INTO events (event_name, event_type, user_id, user_ip) VALUES ('cdc-test', 'click', 42, '10.0.0.1');"

while [ "$(clickhousectl cloud service query --id "$CH_ID" \
  --query "SELECT count() FROM public_events")" != "1000001" ]; do
  sleep 10
done
```

<div id="query-clickhouse-from-postgres">
  ### Interroger ClickHouse depuis Postgres
</div>

L’extension [`pg_clickhouse`](/docs/fr/products/managed-postgres/extensions/pg_clickhouse/introduction) permet à Postgres de servir de couche de requête unifiée pour les données transactionnelles et analytiques. Récupérez le nom d’hôte HTTPS de ClickHouse, puis configurez l’extension via `psql` :

```bash theme={null}
CH_HOST=$(clickhousectl cloud service get "$CH_ID" --json \
  | jq -r '.endpoints[] | select(.protocol=="https") | .host')

psql "$PG_URL" <<SQL
CREATE EXTENSION pg_clickhouse;
CREATE SERVER ch FOREIGN DATA WRAPPER clickhouse_fdw
       OPTIONS(driver 'http', host '$CH_HOST', dbname 'default', port '8443');
CREATE USER MAPPING FOR CURRENT_USER SERVER ch
       OPTIONS (user 'default', password '$CH_PASSWORD');
CREATE SCHEMA organization;
IMPORT FOREIGN SCHEMA "default" FROM SERVER ch INTO organization;
SQL
```

Le heredoc est volontairement non guillemeté, afin que le shell substitue `$CH_HOST` et `$CH_PASSWORD` avant que le SQL n'arrive à Postgres. Les tables répliquées sont désormais visibles comme des tables étrangères dans le schéma `organization` ; les requêtes qui les ciblent s'exécutent dans ClickHouse.

Mesurées sur `c6gd.large` avec ce jeu de données, les requêtes analytiques s'exécutent 6 à 9 fois plus vite via les tables étrangères (par exemple, un GROUP BY avec 5 agrégations : 176 ms via ClickHouse contre 1 133 ms en local ; un JOIN avec agrégations : 298 ms contre 2 764 ms).

<div id="cleanup-resources">
  ## Nettoyage
</div>

Supprimez d’abord le ClickPipe, puis le service Postgres. La suppression d’un service entraîne la suppression définitive de toutes ses données :

```bash theme={null}
clickhousectl cloud clickpipe delete "$CH_ID" "$PIPE_ID"
clickhousectl cloud postgres delete "$PG_ID"
```

Un service ClickHouse en cours d’exécution ne peut pas être supprimé directement. Arrêtez-le, attendez qu’il soit `stopped`, puis supprimez-le :

```bash theme={null}
clickhousectl cloud service stop "$CH_ID"

while [ "$(clickhousectl cloud service get "$CH_ID" --json | jq -r .state)" != "stopped" ]; do
  sleep 10
done

clickhousectl cloud service delete "$CH_ID"
```
