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

> 원격 PostgreSQL 서버에 저장된 데이터에서 `SELECT` 및 `INSERT` 쿼리를 수행할 수 있습니다.

# postgresql

원격 PostgreSQL 서버에 저장된 데이터에서 `SELECT` 및 `INSERT` 쿼리를 수행할 수 있습니다.

<div id="syntax">
  ## 구문
</div>

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

<div id="arguments">
  ## 인수
</div>

| 인수            | 설명                                                                               |
| ------------- | -------------------------------------------------------------------------------- |
| `host:port`   | PostgreSQL 서버의 주소입니다.                                                            |
| `database`    | 원격 데이터베이스 이름입니다.                                                                 |
| `table`       | 원격 테이블 이름 또는 PostgreSQL에 그대로 전달되는 쿼리입니다([테이블 이름 대신 쿼리 전달](#passing-a-query) 참고). |
| `user`        | PostgreSQL 사용자 이름입니다.                                                            |
| `password`    | 사용자 비밀번호입니다.                                                                     |
| `schema`      | 기본 스키마가 아닌 테이블 스키마입니다. 선택 사항입니다.                                                 |
| `on_conflict` | 충돌 해결 전략입니다. 예시: `ON CONFLICT DO NOTHING`. 선택 사항입니다.                             |

인수는 [이름이 지정된 컬렉션](/docs/ko/concepts/features/configuration/server-config/named-collections)을 사용해 전달할 수도 있습니다. 이 경우 `host`와 `port`는 별도로 지정해야 합니다. 프로덕션 환경에서는 이 방식을 권장합니다.

<div id="returned_value">
  ## 반환 값
</div>

원본 PostgreSQL 테이블과 동일한 컬럼으로 구성된 테이블 객체입니다.

<Note>
  컬럼 이름 목록이 포함된 테이블 이름과 테이블 함수 `postgresql(...)`를 `INSERT` 쿼리에서 구분하려면 `FUNCTION` 또는 `TABLE FUNCTION` 키워드를 사용해야 합니다. 아래 예시를 참조하십시오.
</Note>

<div id="settings">
  ## 설정
</div>

`postgresql` 테이블 함수(및 [`PostgreSQL`](/docs/ko/reference/engines/table-engines/integrations/postgresql) 테이블 엔진)에서 사용하는 연결 풀은 끝에 추가하는 `SETTINGS` 절로 구성할 수 있습니다. 설정을 지정하지 않으면 해당 쿼리 수준의 `postgresql_*` 설정 값이 기본값으로 사용됩니다. `postgresql_connection_pool_*` 및 `postgresql_connection_attempt_timeout` 설정의 전체 목록과 기본값은 테이블 엔진의 [설정](/docs/ko/reference/engines/table-engines/integrations/postgresql#settings) 섹션을 참조하십시오.

예시:

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

<div id="implementation-details">
  ## 구현 세부 사항
</div>

PostgreSQL 측의 `SELECT` 쿼리는 각 `SELECT` 쿼리 후 커밋되는 읽기 전용 PostgreSQL 트랜잭션 내에서 `COPY (SELECT ...) TO STDOUT` 형태로 실행됩니다.

`=`, `!=`, `>`, `>=`, `<`, `<=`, `IN`과 같은 단순한 `WHERE` 절은 PostgreSQL 서버에서 실행됩니다.

모든 조인, 집계, 정렬, `IN [ array ]` 조건 및 `LIMIT` 샘플링 제약은 PostgreSQL 쿼리가 완료된 후에만 ClickHouse에서 실행됩니다.

<div id="passing-a-query">
  ## 테이블 이름 대신 쿼리 전달하기
</div>

테이블 이름 대신 세 번째 인수로 PostgreSQL에 그대로 전달되는 `SELECT` 쿼리를 사용할 수 있습니다. 결과 테이블의 구조는 쿼리 결과로부터 추론됩니다. 쿼리는 서브쿼리로 작성하거나 `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');
```

이는 조인, 집계 또는 기타 처리를 PostgreSQL로 푸시다운하는 데 유용합니다. 이러한 테이블은 읽기 전용이므로 `INSERT`는 허용되지 않습니다. 동일한 구문이 [`PostgreSQL`](/docs/ko/reference/engines/table-engines/integrations/postgresql) 테이블 엔진에서도 지원됩니다.

<Note>
  `(SELECT ...)` 형태의 서브쿼리는 서버로 전송되기 전에 ClickHouse에서 파싱된 다음 PostgreSQL 방언(PostgreSQL 식별자 인용 및 문자열 리터럴 이스케이프)으로 다시 직렬화됩니다. 따라서 유효한 ClickHouse SQL이어야 합니다. ClickHouse가 파싱하지 않는 PostgreSQL 전용 구문을 전달하려면 텍스트가 PostgreSQL로 그대로 전송되는 `query('...')` 형식을 사용하십시오.

  바깥쪽 ClickHouse 쿼리의 외부 `WHERE`, `LIMIT`, 집계 등은 전달된 쿼리로 **푸시다운되지 않습니다** — 전체 쿼리 결과를 가져온 후 ClickHouse에서 적용됩니다. PostgreSQL에서 읽는 데이터를 제한하려면 필터를 전달된 쿼리 내부에 넣으십시오. [`external_table_strict_query = 1`](/docs/ko/reference/settings/session-settings#external_table_strict_query)을 사용하면 푸시다운할 수 없는 외부 필터는 로컬에서 적용되는 대신 예외와 함께 거부됩니다.
</Note>

PostgreSQL 측의 `INSERT` 쿼리는 각 `INSERT` 문 후 자동 커밋되는 PostgreSQL 트랜잭션 내에서 `COPY \"table_name\" (field1, field2, ... fieldN) FROM STDIN` 형태로 실행됩니다.

PostgreSQL 배열 타입은 ClickHouse 배열로 변환됩니다.

<Note>
  주의하십시오. PostgreSQL에서는 Integer\[]와 같은 배열 데이터 타입 컬럼에 행마다 서로 다른 차원의 배열이 들어갈 수 있지만, ClickHouse에서는 모든 행에서 동일한 차원의 다차원 배열만 허용됩니다.
</Note>

여러 레플리카를 지원하며, `|`로 구분해 나열해야 합니다. 예시는 다음과 같습니다:

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

또는

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

PostgreSQL 딕셔너리 소스의 레플리카 우선순위를 지원합니다. 맵의 숫자가 클수록 우선순위는 낮아집니다. 가장 높은 우선순위는 `0`입니다.

<div id="examples">
  ## 예시
</div>

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

일반 인수를 사용해 ClickHouse에서 데이터 선택하기:

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

또는 [이름이 지정된 컬렉션](/docs/ko/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 │           ᴺᵁᴸᴸ │
└────────┴──────────────┴───────┴──────┴────────────────┘
```

삽입:

```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 │      │           ᴺᵁᴸᴸ │
└────────┴──────────────┴───────┴──────┴────────────────┘
```

기본 스키마가 아닌 스키마 사용:

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

<div id="related">
  ## 관련 항목
</div>

* [PostgreSQL 테이블 엔진](/docs/ko/reference/engines/table-engines/integrations/postgresql)
* [PostgreSQL을 딕셔너리 소스로 사용하기](/docs/ko/reference/statements/create/dictionary/sources/postgresql)

<div id="replicating-or-migrating-postgres-data-with-peerdb">
  ### PeerDB를 사용해 Postgres 데이터를 복제하거나 마이그레이션하기
</div>

> 테이블 함수 외에도 ClickHouse의 [PeerDB](https://docs.peerdb.io/introduction)를 사용하면 Postgres에서 ClickHouse로 이어지는 연속적인 데이터 파이프라인을 언제든지 설정할 수 있습니다. PeerDB는 CDC(Change Data Capture)를 사용해 Postgres에서 ClickHouse로 데이터를 복제하도록 특별히 설계된 도구입니다.
