All Products
Search
Document Center

Hologres:COPY

Last Updated:Sep 19, 2026

Gunakan COPY FROM STDIN untuk memuat data ke Hologres dan COPY TO STDOUT untuk mengekspornya. Hologres memperluas sintaks COPY PostgreSQL standar dengan dua parameter khusus Hologres: STREAM_MODE (mode copy tetap) dan ON_CONFLICT (kebijakan konflik primary key).

Semua pernyataan COPY harus dijalankan melalui PostgreSQL client. Untuk detail koneksi, lihat PostgreSQL client.

Untuk memantau operasi COPY, kueri hologres.hg_query_log. Di Hologres V3.0 dan versi lebih baru, setiap operasi COPY menghasilkan dua catatan log—satu untuk perintah COPY dan satu untuk pernyataan INSERT yang mendasarinya—yang dihubungkan melalui ID transaksi. Lihat Query log untuk detailnya.

Batasan

  • COPY FROM hanya menulis ke tabel partisi anak, bukan tabel partisi induk.

  • COPY FROM STDIN mendukung tabel dengan kendala DEFAULT atau kolom SERIAL mulai dari Hologres V1.1.43. Versi sebelumnya tidak mendukung jenis tabel ini.

Sintaks

/* Impor data */
COPY table_name [ ( column_name [, ...] ) ]
    FROM STDIN
    [ [ WITH ] ( option [, ...] ) ]

/* Ekspor data */
COPY { ( query ) }
    TO STDOUT
    [ [ WITH ] ( option [, ...] ) ]

Dengan option dapat berupa salah satu berikut:

FORMAT format_name                        -- TEXT (default), CSV, atau BINARY
DELIMITER 'delimiter_character'
NULL 'null_string'
HEADER [ boolean ]                        -- hanya CSV
QUOTE 'quote_character'                   -- hanya CSV
ESCAPE 'escape_character'                 -- hanya CSV
FORCE_QUOTE { ( column_name [, ...] ) | * }  -- CSV, hanya COPY TO
FORCE_NOT_NULL ( column_name [, ...] )    -- CSV, hanya COPY FROM
ENCODING 'encoding_name'
STREAM_MODE [ boolean ]                   -- khusus Hologres; hanya COPY FROM
ON_CONFLICT 'none|ignore|update'          -- khusus Hologres; hanya COPY FROM

Parameter

ParameterDeskripsi
table_nameTabel Hologres tempat mengimpor data.
queryPernyataan SELECT yang hasilnya diekspor.
STDINMembaca input dari standard input klien.
STDOUTMenulis output ke standard output klien.
FORMATFormat file: TEXT (default), CSV, atau BINARY. Impor BINARY hanya didukung dalam mode copy tetap (STREAM_MODE TRUE).
DELIMITERPemisah kolom. Default: tab (\t) untuk TEXT, koma (,) untuk CSV. Contoh: DELIMITER AS ','.
NULLString yang merepresentasikan nilai null. Default: \N untuk TEXT, string kosong tanpa tanda kutip untuk CSV. Tidak didukung untuk BINARY.
HEADERApakah file mencakup baris header. Hanya untuk CSV.
QUOTEKarakter satu byte yang digunakan untuk mengapit nilai bidang. Hanya untuk CSV. Default: ".
ESCAPEKarakter satu byte yang mendahului kecocokan QUOTE. Hanya untuk CSV. Default: sama dengan QUOTE.
FORCE_QUOTEMewajibkan pengutipan untuk semua nilai non-NULL di kolom yang ditentukan. Berlaku hanya untuk CSV dan COPY TO.
FORCE_NOT_NULLMemperlakukan string representasi null sebagai string dengan panjang nol, bukan NULL. CSV, hanya untuk COPY FROM.
ENCODINGEnkoding file. Default: enkoding klien.
STREAM_MODEMengaktifkan mode copy tetap untuk impor. Default: FALSE. Ketika TRUE, menggunakan rencana eksekusi tetap dengan lock tingkat baris alih-alih lock tingkat tabel. Hanya untuk COPY FROM.
ON_CONFLICTKebijakan konflik saat terjadi tabrakan primary key. Nilainya tidak peka huruf besar/kecil tanpa tanda kutip; dengan tanda kutip tunggal, gunakan huruf kecil (misalnya, 'none'). Hanya untuk COPY FROM. Lihat Perilaku ON_CONFLICT berdasarkan versi.

Nilai ON_CONFLICT:

NilaiPerilakuKapan digunakan
NONEMelaporkan error saat terjadi konflik.Integritas data ketat — setiap baris harus baru.
IGNOREMelewatkan baris yang konflik.Pemuatan idempoten di mana duplikat diharapkan dan catatan yang ada harus dipertahankan.
UPDATEMenimpa baris yang konflik.Pola upsert di mana nilai terbaru yang menang.

Perilaku ON_CONFLICT berdasarkan versi

  • Sebelum V3.0.4: ON_CONFLICT hanya berlaku ketika STREAM_MODE TRUE.

  • V3.0.4 dan versi lebih baru: ON_CONFLICT juga berlaku ketika STREAM_MODE FALSE, dengan parameter GUC hg_experimental_copy_enable_on_conflict diaktifkan. Ketika STREAM_MODE FALSE, UPDATE memerlukan penulisan semua kolom.

  • V3.1.1 dan versi lebih baru: Ketika STREAM_MODE FALSE, UPDATE mendukung impor parsial-kolom (hg_experimental_copy_enable_on_conflict diaktifkan secara default).

Atomicitas

COPY standar (STREAM_MODE FALSE) menjamin atomicitas: seluruh operasi berhasil atau dikembalikan (rollback).

Mode copy tetap (STREAM_MODE TRUE) menggunakan lock tingkat baris alih-alih lock tingkat tabel, sehingga atomicitas tidak dijamin. Jika suatu baris berisi data tidak valid, error dilaporkan hanya untuk baris tersebut—baris lainnya mungkin sebagian tertulis atau tidak tertulis sama sekali.

Query log

Di Hologres V3.0 dan versi lebih baru, setiap operasi COPY menghasilkan dua catatan di hologres.hg_query_log: satu untuk perintah COPY dan satu untuk INSERT yang dijalankannya secara internal. Hubungkan keduanya menggunakan ID transaksi:

SELECT
    query_id,
    query,
    extended_info
FROM
    hologres.hg_query_log
WHERE
    extended_info ->> 'source_trx' = '<transaction_id>'  -- Dapatkan ID transaksi dari field trans_id dalam catatan log COPY
ORDER BY
    query_start;

Pada versi sebelum V3.0, setiap operasi COPY menghasilkan satu catatan saja.

Impor data ke Hologres

Impor dari PostgreSQL client (stdin)

PostgreSQL client hanya dapat membaca dari stdin. Konsol HoloWeb tidak mendukung impor stdin.

Contoh 1: Impor teks berpemisah

-- Buat tabel target
CREATE TABLE copy_test (
    id    int,
    age   int,
    name  text
);

-- Impor data dari stdin
COPY copy_test FROM STDIN WITH DELIMITER AS ',' NULL AS '';
53444,24,wangming
55444,38,ligang
55444,38,luyong
\.

-- Verifikasi
SELECT * FROM copy_test;

Contoh 2: Impor file CSV

-- Buat tabel target
CREATE TABLE partsupp (
    ps_partkey     integer NOT NULL,
    ps_suppkey     integer NOT NULL,
    ps_availqty    integer NOT NULL,
    ps_supplycost  float   NOT NULL,
    ps_comment     text    NOT NULL
);

-- Impor CSV dari stdin
COPY partsupp FROM STDIN WITH DELIMITER '|' CSV;
1|2|3325|771.64|final theodolites
1|25002|8076|993.49|ven ideas
\.

-- Verifikasi
SELECT * FROM partsupp;

Contoh 3: Impor file lokal menggunakan psql

Arahkan file lokal ke stdin dengan operator redirect shell psql:

psql -U <username> -p <port> -h <endpoint> -d <databasename> \
    -c "COPY <table> FROM STDIN WITH DELIMITER '|' CSV;" <<filename>;
ParameterDeskripsiContoh
usernameAkun Alibaba Cloud: ID AccessKey. Akun kustom: username (misalnya, BASIC$abc). Simpan ID AccessKey dalam variabel lingkungan untuk menghindari eksposurnya dalam perintah.—
portPort publik instans Hologres.80
endpointTitik akhir publik instans Hologres.xxx-cn-hangzhou.hologres.aliyuncs.com
databasenameNama database Hologres.mydb
tableNama tabel target.—
filenamePath ke file lokal.D:\tmp\copy_test.csv

Contoh berikut mengimpor file lokal copy_test menggunakan perintah ini:

11212

File berisi:

01,01,name1
02,01,name2
03,01,name3
04,01,name4

Setelah impor, kueri hasilnya di psql:

查询结果

Impor dari klien JDBC menggunakan CopyManager

Klien Java Database Connectivity (JDBC) dapat menggunakan CopyManager—wrapper API driver JDBC PostgreSQL untuk COPY—untuk mengalirkan file ke Hologres.

package com.aliyun.hologram.test.jdbc;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;

import org.postgresql.copy.CopyManager;
import org.postgresql.core.BaseConnection;

public class jdbcCopyFile {

    public static void main(String args[]) throws Exception {
        System.out.println(copyFromFile(getConnection(), "/Users/feng/Workspace/region.tbl", "region"));
    }

    public static Connection getConnection() throws Exception {
        Class.forName("org.postgresql.Driver");
        String url = "jdbc:postgresql://endpoint:port/dbname";
        Properties props = new Properties();
        // Simpan kredensial dalam variabel lingkungan untuk menghindari hardcoding
        props.setProperty("user", "AAA");     // ID AccessKey
        props.setProperty("password", "BBB"); // Rahasia AccessKey
        return DriverManager.getConnection(url, props);
    }

    /**
     * Mengalirkan file lokal ke Hologres melalui COPY FROM STDIN.
     *
     * @param connection  Koneksi JDBC aktif
     * @param filePath    Path ke file lokal
     * @param tableName   Tabel Hologres target
     * @return Jumlah baris yang diimpor
     */
    public static long copyFromFile(Connection connection, String filePath, String tableName)
            throws SQLException, IOException {
        long count = 0;
        FileInputStream fileInputStream = null;

        try {
            CopyManager copyManager = new CopyManager((BaseConnection) connection);
            fileInputStream = new FileInputStream(filePath);
            count = copyManager.copyIn("COPY " + tableName + " FROM STDIN delimiter '|' csv", fileInputStream);
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return count;
    }
}

Mode copy tetap

Mode copy tetap (STREAM_MODE TRUE) menggunakan rencana eksekusi tetap yang telah dikompilasi sebelumnya untuk mempercepat impor COPY berulang. Ini adalah optimisasi khusus Hologres yang tersedia sejak V1.3.17 dan hanya berlaku untuk impor. Untuk perbandingan dengan mode penulisan batch lainnya, lihat Perbandingan mode penulisan batch. Untuk mekanisme dasarnya, lihat Percepat eksekusi SQL dengan rencana tetap.

Menulis ke subset kolom — pembaruan parsial

Ketika ON_CONFLICT UPDATE diatur dan COPY hanya menulis ke beberapa kolom, kolom yang tidak termasuk dalam daftar COPY tidak dimodifikasi:

CREATE TABLE t0 (id int NOT NULL, name text, age int, primary key(id));

COPY t0(id, name) FROM STDIN
WITH (
    STREAM_MODE TRUE,
    ON_CONFLICT UPDATE
);

-- Pernyataan INSERT INTO yang setara:
INSERT INTO t0(id, name) VALUES(?, ?)
ON CONFLICT(id) DO UPDATE SET
    id = excluded.id, name = excluded.name;

Menulis ke subset kolom — kolom dengan nilai default

Ketika kolom yang tidak termasuk dalam daftar COPY memiliki nilai DEFAULT, Hologres menerapkan nilai default hanya untuk baris baru. Baris yang sudah ada dan cocok berdasarkan primary key tidak diperbarui untuk kolom tersebut:

CREATE TABLE t0 (id int NOT NULL, name text, age int DEFAULT 0, primary key(id));

COPY t0(id, name) FROM STDIN
WITH (
    STREAM_MODE TRUE,
    ON_CONFLICT UPDATE
);

-- Pernyataan INSERT INTO yang setara:
-- Untuk baris baru (tidak ada id yang cocok), age diatur ke nilai default-nya.
-- Untuk baris yang sudah ada (id yang cocok), age tidak diperbarui.
INSERT INTO t0(id, name, age) VALUES(?, ?, DEFAULT)
ON CONFLICT(id) DO UPDATE SET
    id = excluded.id, name = excluded.name;

Ekspor data dari Hologres

Ekspor ke file lokal

Kedua metode berikut hanya tersedia pada PostgreSQL client.

Menggunakan meta-perintah `\copy` (psql)

-- Buat dan isi tabel
CREATE TABLE copy_to_local (
    id    int,
    age   int,
    name  text
);

INSERT INTO copy_to_local VALUES
    (1, 1, 'a'),
    (1, 2, 'b'),
    (1, 3, 'c'),
    (1, 4, 'd');

-- Ekspor ke file lokal
\COPY (SELECT * FROM copy_to_local) TO '/root/localfile.txt';

Menggunakan pengalihan stdout (psql)

psql -U <username> -p <port> -h <endpoint> -d <databasename> \
    -c "COPY (SELECT * FROM <tablename>) TO STDOUT WITH DELIMITER '|' CSV;" > <filename>

Ekspor ke Object Storage Service (OSS)

Gunakan program hg_dump_to_oss dengan COPY TO PROGRAM untuk mengekspor data Hologres ke bucket OSS. Setiap ekspor dibatasi hingga 5 GB.

Prasyarat

Hanya superuser dan pengguna dengan role pg_execute_server_program yang dapat menjalankan hg_dump_to_oss. Berikan role tersebut sebagai berikut:

-- Model izin sederhana (SPM)
CALL spm_grant('pg_execute_server_program', '<ID akun Alibaba Cloud, alamat email, atau akun Pengguna RAM>');

-- Model otorisasi PostgreSQL standar
GRANT pg_execute_server_program TO <account>;

Sintaks

COPY (query) TO PROGRAM 'hg_dump_to_oss
    --AccessKeyId <access_key_id>
    --AccessKeySecret <access_key_secret>
    --Endpoint <oss_classic_network_endpoint>
    --BucketName <bucket_name>
    --DirName <directory>
    [--FileName <file_name>]
    [--BatchSize <n>]'
(DELIMITER ',', HEADER true, FORMAT CSV);
Penting

DirName tidak boleh diawali dengan / atau \.

Parameter

ParameterDeskripsiContoh
queryPernyataan SELECT yang hasilnya diekspor.SELECT * FROM dual;
AccessKeyIdID AccessKey. Simpan dalam variabel lingkungan untuk menghindari eksposur kredensial.—
AccessKeySecretRahasia AccessKey. Simpan dalam variabel lingkungan.—
EndpointTitik akhir jaringan klasik bucket OSS. Gunakan titik akhir jaringan klasik, bukan titik akhir publik atau VPC. Temukan di halaman detail bucket atau di Wilayah dan titik akhir OSS.oss-cn-beijing-internal.aliyuncs.com
BucketNameNama bucket OSS.dummy_bucket
DirNamePath direktori OSS. Tidak boleh diawali dengan / atau \.testdemo/
FileName(Opsional) Nama file output. Tidak boleh mengandung: `` ; # '? ~ < ( ) " $ \ { } [ ] & * \n \r ``.file_name
BatchSizeBaris yang diproses per batch. Default: 1000.5000
DELIMITERPemisah bidang dalam file output. Default: tab (\t).,

Contoh

-- Ekspor dari tabel internal Hologres ke OSS
COPY (SELECT * FROM holo_test LIMIT 2)
TO PROGRAM 'hg_dump_to_oss
    --AccessKeyId <access_id>
    --AccessKeySecret <access_key>
    --Endpoint oss-cn-hangzhou-internal.aliyuncs.com
    --BucketName hologres-demo
    --DirName holotest/
    --FileName file_name
    --BatchSize 3000'
DELIMITER ',';

-- Ekspor dari tabel eksternal Hologres ke OSS
COPY (SELECT * FROM foreign_holo_test LIMIT 20)
TO PROGRAM 'hg_dump_to_oss
    --AccessKeyId <access_id>
    --AccessKeySecret <access_key>
    --Endpoint oss-cn-hangzhou-internal.aliyuncs.com
    --BucketName hologres-demo
    --DirName holotest/
    --FileName file_name
    --BatchSize 3000'
(DELIMITER ',', HEADER true);

-- Ekspor ke bucket OSS di wilayah berbeda
-- (misalnya, dari instans Hologres di Tiongkok (Hangzhou) ke bucket OSS di Tiongkok (Beijing))
COPY (SELECT * FROM holo_test_1 LIMIT 20)
TO PROGRAM 'hg_dump_to_oss
    --AccessKeyId <access_id>
    --AccessKeySecret <access_key>
    --Endpoint oss-cn-beijing-internal.aliyuncs.com
    --BucketName hologres-demo
    --DirName holotest/
    --FileName file_name
    --BatchSize 3000'
(DELIMITER ',', HEADER true, FORMAT CSV);

Pemecahan Masalah

ErrorPenyebabSolusi
ERROR: syntax error at or near ")" LINE 1: COPY (select 1,2,3 from ) TO PROGRAM 'hg_dump_to_oss2 --Acce...Parameter query berisi pernyataan SQL tidak valid.Perbaiki sintaks kueri.
DETAIL: child process exited with exit code 255Titik akhir OSS menggunakan jenis jaringan yang salah.Gunakan titik akhir jaringan klasik bucket OSS.
DETAIL: command not foundArgumen PROGRAM tidak diatur ke hg_dump_to_oss.Perbaiki nama program.
DETAIL: child process exited with exit code 101ID AccessKeyId tidak valid.Gunakan ID AccessKey yang valid.
DETAIL: child process exited with exit code 102Rahasia AccessKeySecret tidak valid.Gunakan rahasia AccessKey yang benar.
DETAIL: child process exited with exit code 103Titik akhir Endpoint tidak valid.Gunakan titik akhir jaringan klasik untuk bucket OSS.
DETAIL: child process exited with exit code 104Nama BucketName tidak valid.Verifikasi nama bucket.
DETAIL: child process exited with exit code 105Parameter yang diperlukan tidak ada.Pastikan semua parameter yang diperlukan telah ditentukan.
ERROR: program "hg_dump_to_oss ..." failed DETAIL: child process exited with exit code 255Instans Hologres tidak dapat menjangkau jaringan OSS.Beralih ke titik akhir jaringan klasik. Untuk detail titik akhir, lihat Wilayah dan titik akhir OSS.

Ekspor dari klien JDBC menggunakan CopyManager

import org.postgresql.copy.CopyManager;
import org.postgresql.core.BaseConnection;

import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class copy_to_local_file {

    public static void main(String args[]) throws Exception {
        System.out.println(copyToFile(getConnection(), "/Users/feng/Workspace/region.tbl", "select * from region"));
    }

    public static Connection getConnection() throws Exception {
        Class.forName("org.postgresql.Driver");
        String url = "jdbc:postgresql://endpoint:port/dbname";
        Properties props = new Properties();
        // Simpan kredensial dalam variabel lingkungan untuk menghindari hardcoding
        props.setProperty("user", "AAA");     // ID AccessKey
        props.setProperty("password", "BBB"); // Rahasia AccessKey
        return DriverManager.getConnection(url, props);
    }

    /**
     * Mengalirkan hasil kueri Hologres ke file lokal melalui COPY TO STDOUT.
     *
     * @param connection  Koneksi JDBC aktif
     * @param filePath    Path file tujuan
     * @param SQL_Query   Pernyataan SELECT untuk diekspor
     * @return Path file yang ditulis
     */
    public static String copyToFile(Connection connection, String filePath, String SQL_Query)
            throws SQLException, IOException {

        FileOutputStream fileOutputStream = null;

        try {
            CopyManager copyManager = new CopyManager((BaseConnection) connection);
            fileOutputStream = new FileOutputStream(filePath);
            copyManager.copyOut("COPY (" + SQL_Query + ") TO STDOUT DELIMITER '|' csv", fileOutputStream);
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return filePath;
    }
}

Langkah Selanjutnya