pg_parquet

在PostgreSQL与本地/S3中的Parquet文件复制数据

概览

扩展包名版本分类许可证语言
pg_parquet0.5.1OLAPPostgreSQLRust
ID扩展名BinLibLoadCreateTrustReloc模式
2480pg_parquet-
相关扩展pg_analytics pg_duckdb duckdb_fdw citus_columnar columnar pg_mooncake aws_s3 citus

manual update from 0.16.0

版本

类型仓库版本PG 大版本包名依赖
EXTPIGSTY0.5.11817161514pg_parquet-
RPMPIGSTY0.5.11817161514pg_parquet_$v-
DEBPIGSTY0.5.11817161514postgresql-$v-pg-parquet-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
el8.aarch64
el9.x86_64
el9.aarch64
el10.x86_64
el10.aarch64
d12.x86_64
d12.aarch64
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
d13.x86_64
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
d13.aarch64
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
u22.x86_64
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
u22.aarch64
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
u24.x86_64
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
u24.aarch64
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1
PIGSTY 0.5.1

构建

您可以使用 pig build 命令构建 pg_parquet 扩展的 RPM / DEB 包:

pig build pkg pg_parquet         # 构建 RPM / DEB 包

安装

您可以直接安装 pg_parquet 扩展包的预置二进制包,首先确保 PGDGPIGSTY 仓库已经添加并启用:

pig repo add pgsql -u          # 添加仓库并更新缓存

使用 pig 或者是 apt/yum/dnf 安装扩展:

pig install pg_parquet;          # 当前活跃 PG 版本安装
pig ext install -y pg_parquet -v 18  # PG 18
pig ext install -y pg_parquet -v 17  # PG 17
pig ext install -y pg_parquet -v 16  # PG 16
pig ext install -y pg_parquet -v 15  # PG 15
pig ext install -y pg_parquet -v 14  # PG 14
dnf install -y pg_parquet_18       # PG 18
dnf install -y pg_parquet_17       # PG 17
dnf install -y pg_parquet_16       # PG 16
dnf install -y pg_parquet_15       # PG 15
dnf install -y pg_parquet_14       # PG 14
apt install -y postgresql-18-pg-parquet   # PG 18
apt install -y postgresql-17-pg-parquet   # PG 17
apt install -y postgresql-16-pg-parquet   # PG 16
apt install -y postgresql-15-pg-parquet   # PG 15
apt install -y postgresql-14-pg-parquet   # PG 14

预加载配置

shared_preload_libraries = 'pg_parquet';

创建扩展

CREATE EXTENSION pg_parquet;

用法

pg_parquet 主要提供以下三项功能:

  1. 将 PostgreSQL 表/查询结果导出为 Parquet 文件,
  2. 将 Parquet 文件中的数据导入到 PostgreSQL 表中,
  3. 查看 Parquet 文件的模式与元数据信息。

使用 COPY 在 Parquet 文件与 PostgreSQL 表之间导入导出

可以使用 PostgreSQL 的 COPY 命令来读写 Parquet 文件。以下示例演示了如何将包含复合类型的 PostgreSQL 表写入 Parquet 文件,然后再将该 Parquet 文件的内容读回同一张表。

-- 创建复合类型
CREATE TYPE product_item AS (id INT, name TEXT, price float4);
CREATE TYPE product AS (id INT, name TEXT, items product_item[]);

-- 创建包含复合类型的表
CREATE TABLE product_example (
    id int,
    product product,
    products product[],
    created_at TIMESTAMP,
    updated_at TIMESTAMPTZ
);

-- 向表中插入数据
insert into product_example values (
    1,
    ROW(1, 'product 1', ARRAY[ROW(1, 'item 1', 1.0), ROW(2, 'item 2', 2.0), NULL]::product_item[])::product,
    ARRAY[ROW(1, NULL, NULL)::product, NULL],
    now(),
    '2022-05-01 12:00:00-04'
);

-- 将表导出为 Parquet 文件
COPY product_example TO '/tmp/product_example.parquet' (format 'parquet', compression 'gzip');

-- 查看表内容
SELECT * FROM product_example;

-- 将 Parquet 文件导入到表中
COPY product_example FROM '/tmp/product_example.parquet';

-- 查看表内容
SELECT * FROM product_example;

此外,也可以使用 COPY 命令通过标准输入/输出读写 Parquet 流。以下是使用示例(必须指定 format = parquet):

psql -d pg_parquet -p 28817 -h localhost -c "create table product_example_reconstructed (like product_example);"
 CREATE TABLE

psql -d pg_parquet -p 28817 -h localhost -c "copy product_example to stdout (format parquet);" | psql -d pg_parquet -p 28817 -h localhost -c "copy product_example_reconstructed from stdin (format parquet);"
 COPY 2

查看 Parquet 文件模式

调用 SELECT * FROM parquet.schema(<uri>) 可查看指定 URI 处 Parquet 文件的模式信息。

SELECT * FROM parquet.schema('/tmp/product_example.parquet') LIMIT 10;
             uri              |     name     | type_name  | type_length | repetition_type | num_children | converted_type | scale | precision | field_id | logical_type
------------------------------+--------------+------------+-------------+-----------------+--------------+----------------+-------+-----------+----------+--------------
 /tmp/product_example.parquet | arrow_schema |            |             |                 |            5 |                |       |           |          |
 /tmp/product_example.parquet | id           | INT32      |             | OPTIONAL        |              |                |       |           |        0 |
 /tmp/product_example.parquet | product      |            |             | OPTIONAL        |            3 |                |       |           |        1 |
 /tmp/product_example.parquet | id           | INT32      |             | OPTIONAL        |              |                |       |           |        2 |
 /tmp/product_example.parquet | name         | BYTE_ARRAY |             | OPTIONAL        |              | UTF8           |       |           |        3 | STRING
 /tmp/product_example.parquet | items        |            |             | OPTIONAL        |            1 | LIST           |       |           |        4 | LIST
 /tmp/product_example.parquet | list         |            |             | REPEATED        |            1 |                |       |           |          |
 /tmp/product_example.parquet | element        |            |             | OPTIONAL        |            3 |                |       |           |        5 |
 /tmp/product_example.parquet | id           | INT32      |             | OPTIONAL        |              |                |       |           |        6 |
 /tmp/product_example.parquet | name         | BYTE_ARRAY |             | OPTIONAL        |              | UTF8           |       |           |        7 | STRING
(10 rows)

查看 Parquet 元数据

调用 SELECT * FROM parquet.metadata(<uri>) 可查看指定 URI 处 Parquet 文件的详细元数据,例如列统计信息等。

SELECT uri, row_group_id, row_group_num_rows, row_group_num_columns, row_group_bytes, column_id, file_offset, num_values, path_in_schema, type_name FROM parquet.metadata('/tmp/product_example.parquet') LIMIT 1;
             uri              | row_group_id | row_group_num_rows | row_group_num_columns | row_group_bytes | column_id | file_offset | num_values | path_in_schema | type_name
------------------------------+--------------+--------------------+-----------------------+-----------------+-----------+-------------+------------+----------------+-----------
 /tmp/product_example.parquet |            0 |                  1 |                    13 |             842 |         0 |           0 |          1 | id             | INT32
(1 row)
SELECT stats_null_count, stats_distinct_count, stats_min, stats_max, compression, encodings, index_page_offset, dictionary_page_offset, data_page_offset, total_compressed_size, total_uncompressed_size FROM parquet.metadata('/tmp/product_example.parquet') LIMIT 1;
 stats_null_count | stats_distinct_count | stats_min | stats_max |    compression     |        encodings         | index_page_offset | dictionary_page_offset | data_page_offset | total_compressed_size | total_uncompressed_size
------------------+----------------------+-----------+-----------+--------------------+--------------------------+-------------------+------------------------+------------------+-----------------------+-------------------------
                0 |                      | 1         | 1         | GZIP(GzipLevel(6)) | PLAIN,RLE,RLE_DICTIONARY |                   |                      4 |               42 |                   101 |                      61
(1 row)

调用 SELECT * FROM parquet.file_metadata(<uri>) 可查看指定 URI 处 Parquet 文件的文件级元数据,例如格式版本等。

SELECT * FROM parquet.file_metadata('/tmp/product_example.parquet')
             uri              | created_by | num_rows | num_row_groups | format_version
------------------------------+------------+----------+----------------+----------------
 /tmp/product_example.parquet | pg_parquet |        1 |              1 | 1
(1 row)

调用 SELECT * FROM parquet.kv_metadata(<uri>) 可查询指定 URI 处 Parquet 文件的自定义键值元数据。

SELECT uri, encode(key, 'escape') as key, encode(value, 'escape') as value FROM parquet.kv_metadata('/tmp/product_example.parquet');
             uri              |     key      |    value
------------------------------+--------------+---------------------
 /tmp/product_example.parquet | ARROW:schema | /////5gIAAAQAAAA ...
(1 row)

查看 Parquet 列统计信息

调用 SELECT * FROM parquet.column_stats(<uri>) 可查看指定 URI 处 Parquet 文件的列统计信息,例如列的最小值和最大值等。

SELECT * FROM parquet.column_stats('/tmp/product_example.parquet')
 column_id | field_id |         stats_min          |         stats_max          | stats_null_count | stats_distinct_count
-----------+----------+----------------------------+----------------------------+------------------+----------------------
         4 |        7 | item 1                     | item 2                     |                1 |
         6 |       11 | 1                          | 1                          |                1 |
         7 |       12 |                            |                            |                2 |
        10 |       17 |                            |                            |                2 |
         0 |        0 | 1                          | 1                          |                0 |
        11 |       18 | 2025-03-11 14:01:22.045739 | 2025-03-11 14:01:22.045739 |                0 |
         3 |        6 | 1                          | 2                          |                1 |
        12 |       19 | 2022-05-01 19:00:00+03     | 2022-05-01 19:00:00+03     |                0 |
         8 |       15 |                            |                            |                2 |
         5 |        8 | 1                          | 2                          |                1 |
         9 |       16 |                            |                            |                2 |
         1 |        2 | 1                          | 1                          |                0 |
         2 |        3 | product 1                  | product 1                  |                0 |
(13 rows)

最后修改 2026-03-08: add extension catalog (baacba6)