The PostgreSQL engine allows to perform SELECT and INSERT queries on data that is stored on a remote PostgreSQL server.

Creating a Table 

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

See a detailed description of the CREATE TABLE query.

The table structure can differ from the original PostgreSQL table structure:

  • Column names should be the same as in the original PostgreSQL table, but you can use just some of these columns and in any order.
  • Column types may differ from those in the original PostgreSQL table. ClickHouse tries to cast values to the ClickHouse data types.
  • Setting external_table_functions_use_nulls defines how to handle Nullable columns. Default is 1, if 0 - table function will not make nullable columns and will insert default values instead of nulls. This is also applicable for null values inside array data types.

Engine Parameters

  • host:port — PostgreSQL server address.
  • database — Remote database name.
  • table — Remote table name.
  • user — PostgreSQL user.
  • password — User password.
  • schema — Non-default table schema. Optional.

Implementation Details 

SELECT queries on PostgreSQL side run as COPY (SELECT ...) TO STDOUT inside read-only PostgreSQL transaction with commit after each SELECT query.

Simple WHERE clauses such as =, !=, >, >=, <, <=, and IN are executed on the PostgreSQL server.

All joins, aggregations, sorting, IN [ array ] conditions and the LIMIT sampling constraint are executed in ClickHouse only after the query to PostgreSQL finishes.

INSERT queries on PostgreSQL side run as COPY "table_name" (field1, field2, ... fieldN) FROM STDIN inside PostgreSQL transaction with auto-commit after each INSERT statement.

PostgreSQL Array types are converted into ClickHouse arrays.

Replicas priority for PostgreSQL dictionary source is supported. The bigger the number in map, the less the priority. The highest priority is 0.

In the example below replica example01-1 has the highest priority:


Usage Example 

Table in PostgreSQL:

postgres=# CREATE TABLE "public"."test" (
"int_id" SERIAL,
"int_nullable" INT NULL DEFAULT NULL,
"float_nullable" FLOAT NULL DEFAULT NULL,
PRIMARY KEY (int_id));


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

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

Table in ClickHouse, retrieving data from the PostgreSQL table created above:

CREATE TABLE default.postgresql_table
    `float_nullable` Nullable(Float32),
    `str` String,
    `int_id` Int32
ENGINE = PostgreSQL('localhost:5432', 'public', 'test', 'postges_user', 'postgres_password');
SELECT * FROM postgresql_table WHERE str IN ('test');
│           ᴺᵁᴸᴸ │ test │      1 │

Using Non-default Schema:

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)
CREATE TABLE pg_table_schema_with_dots (a UInt32)
        ENGINE PostgreSQL('localhost:5432', 'clickhouse', 'nice.table', 'postgrsql_user', 'password', 'nice.schema');

See Also

Original article

Rating: 4 - 1 votes

Was this content helpful?