Todos os produtos
Search
Central de documentação

Hologres:COPY

Última atualização: Jul 10, 2026

Use COPY FROM STDIN para carregar dados no Hologres e COPY TO STDOUT para exportá-los. O Hologres estende a sintaxe padrão do PostgreSQL COPY com dois parâmetros específicos: STREAM_MODE (modo de cópia fixa) e ON_CONFLICT (política de conflito de chave primária).

Execute todas as instruções COPY em um cliente PostgreSQL. Para obter detalhes sobre a conexão, consulte Cliente PostgreSQL.

Para monitorar operações COPY, consulte hologres.hg_query_log. No Hologres V3.0 e versões posteriores, cada operação COPY gera dois registros de log — um para o comando COPY e outro para a instrução INSERT subjacente — vinculados pelo ID da transação. Consulte Log de consultas para mais detalhes.

Limitações

  • O comando COPY FROM grava apenas em tabelas particionadas filhas, não em tabelas particionadas pai.

  • A partir da versão Hologres V1.1.43, o COPY FROM STDIN oferece suporte a tabelas com restrição DEFAULT ou colunas SERIAL. Versões anteriores não suportam esses tipos de tabela.

Sintaxe

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

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

Onde option pode ser uma das seguintes:

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

Parâmetros

Parâmetro

Descrição

table_name

Tabela do Hologres de destino da importação.

query

Instrução SELECT cujos resultados serão exportados.

STDIN

Lê a entrada padrão do cliente.

STDOUT

Grava na saída padrão do cliente.

FORMAT

Formato do arquivo: TEXT (padrão), CSV ou BINARY. A importação BINARY é suportada apenas no modo de cópia fixa (STREAM_MODE TRUE).

DELIMITER

Separador de colunas. Padrão: tabulação (\t) para TEXT, vírgula (,) para CSV. Exemplo: DELIMITER AS ','.

NULL

String que representa um valor nulo. Padrão: \N para TEXT, string vazia sem aspas para CSV. Não há suporte para BINARY.

HEADER

Indica se o arquivo inclui uma linha de cabeçalho. Apenas para CSV.

QUOTE

Caractere de byte único usado para colocar valores de campo entre aspas. Apenas para CSV. Padrão: ".

ESCAPE

Caractere de byte único que precede uma correspondência de QUOTE. Apenas para CSV. Padrão: igual a QUOTE.

FORCE_QUOTE

Força o uso de aspas para todos os valores não NULL nas colunas especificadas. Apenas para CSV e COPY TO.

FORCE_NOT_NULL

Trata strings de representação nula como strings de comprimento zero em vez de NULL. Apenas para CSV e COPY FROM.

ENCODING

Codificação do arquivo. Padrão: codificação do cliente.

STREAM_MODE

Ativa o modo de cópia fixa para importações. Padrão: FALSE. Quando definido como TRUE, utiliza um plano de execução fixo com bloqueio no nível de linha em vez de bloqueio no nível de tabela. Apenas para COPY FROM.

ON_CONFLICT

Política aplicada quando ocorre colisão de chave primária. Os valores não diferenciam maiúsculas de minúsculas sem aspas; com aspas simples, use letras minúsculas (ex.: 'none'). Apenas para COPY FROM. Consulte Comportamento do ON_CONFLICT por versão.

Valores do ON_CONFLICT:

Valor

Comportamento

Quando usar

NONE

Reporta erro em caso de conflito.

Integridade rigorosa dos dados — cada linha deve ser nova.

IGNORE

Ignora a linha conflitante.

Cargas idempotentes em que duplicatas são esperadas e o registro existente deve ser preservado.

UPDATE

Sobrescreve a linha conflitante.

Padrões de upsert em que o valor mais recente deve prevalecer.

Comportamento do ON_CONFLICT por versão

  • Antes da V3.0.4: O parâmetro ON_CONFLICT só tem efeito quando STREAM_MODE TRUE.

  • V3.0.4 e posteriores: O ON_CONFLICT também entra em vigor quando STREAM_MODE FALSE, desde que o parâmetro GUC hg_experimental_copy_enable_on_conflict esteja ativado. Com STREAM_MODE FALSE, a opção UPDATE exige a gravação de todas as colunas.

  • V3.1.1 e posteriores: Quando STREAM_MODE FALSE, o UPDATE suporta importações de colunas parciais (o parâmetro hg_experimental_copy_enable_on_conflict vem ativado por padrão).

Atomicidade

O COPY padrão (STREAM_MODE FALSE) garante atomicidade: toda a operação é concluída com sucesso ou revertida.

Já o modo de cópia fixa (STREAM_MODE TRUE) utiliza bloqueio no nível de linha em vez de bloqueio no nível de tabela; portanto, não há garantia de atomicidade. Se uma linha contiver dados inválidos, o sistema reportará erro apenas para essa linha — as linhas restantes podem ser gravadas parcialmente ou não ser gravadas.

Log de consultas

No Hologres V3.0 e versões posteriores, cada operação COPY gera dois registros em hologres.hg_query_log: um para o comando COPY e outro para o INSERT executado internamente. Vincule-os usando o ID da transação:

SELECT
    query_id,
    query,
    extended_info
FROM
    hologres.hg_query_log
WHERE
    extended_info ->> 'source_trx' = '<transaction_id>'  -- Get the transaction ID from the trans_id field in the COPY log record
ORDER BY
    query_start;

Em versões anteriores à V3.0, cada operação COPY gera um único registro.

Importar dados para o Hologres

Importar de um cliente PostgreSQL (stdin)

O cliente PostgreSQL lê apenas da entrada padrão (stdin). O console HoloWeb não suporta importações via stdin.

Exemplo 1: Importar texto delimitado

-- Create the target table
CREATE TABLE copy_test (
    id    int,
    age   int,
    name  text
);

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

-- Verify
SELECT * FROM copy_test;

Exemplo 2: Importar um arquivo CSV

-- Create the target table
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
);

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

-- Verify
SELECT * FROM partsupp;

Exemplo 3: Importar um arquivo local usando psql

Redirecione um arquivo local para stdin usando o operador de redirecionamento do shell psql:

psql -U <username> -p <port> -h <endpoint> -d <databasename> \
    -c "COPY <table> FROM STDIN WITH DELIMITER '|' CSV;" <<filename>;

Parâmetro

Descrição

Exemplo

username

Conta Alibaba Cloud: AccessKey ID. Conta personalizada: nome de usuário (ex.: BASIC$abc). Armazene o AccessKey ID em uma variável de ambiente para evitar expô-lo nos comandos.

port

Porta pública da instância Hologres.

80

endpoint

Endpoint público da instância Hologres.

xxx-cn-hangzhou.hologres.aliyuncs.com

databasename

Nome do banco de dados Hologres.

mydb

table

Nome da tabela de destino.

filename

Caminho para o arquivo local.

D:\tmp\copy_test.csv

O exemplo a seguir importa o arquivo local copy_test usando este comando:

11212

O arquivo contém:

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

Após a importação, consulte os resultados no psql:

查询结果

Importar de um cliente JDBC usando CopyManager

Clientes Java Database Connectivity (JDBC) podem usar o CopyManager — wrapper de API do driver JDBC PostgreSQL para COPY — para transmitir arquivos para o 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();
        // Store credentials in environment variables to avoid hardcoding them
        props.setProperty("user", "AAA");     // AccessKey ID
        props.setProperty("password", "BBB"); // AccessKey secret
        return DriverManager.getConnection(url, props);
    }

    /**
     * Streams a local file into Hologres via COPY FROM STDIN.
     *
     * @param connection  Active JDBC connection
     * @param filePath    Path to the local file
     * @param tableName   Target Hologres table
     * @return Number of rows imported
     */
    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;
    }
}

Modo de cópia fixa

O modo de cópia fixa (STREAM_MODE TRUE) usa planos de execução fixos pré-compilados para acelerar importações COPY repetidas. Trata-se de uma otimização específica do Hologres disponível desde a versão V1.3.17 e aplica-se apenas a importações. Para comparar com outros modos de gravação em lote, consulte Comparação de modos de gravação em lote. Para entender o mecanismo subjacente, veja Acelerar execução SQL com plano fixo.

Gravar em um subconjunto de colunas — atualização parcial

Quando ON_CONFLICT UPDATE está definido e o COPY grava apenas em algumas colunas, as colunas fora da lista do COPY permanecem inalteradas:

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

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

Gravar em um subconjunto de colunas — colunas com valores padrão

Se uma coluna fora da lista do COPY tiver um valor DEFAULT, o Hologres aplicará o padrão apenas para novas linhas. Linhas existentes que correspondem à chave primária não terão essa coluna atualizada:

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

-- Equivalent INSERT INTO statement:
-- For a new row (no matching id), age is set to its default value.
-- For an existing row (matching id), age is not updated.
INSERT INTO t0(id, name, age) VALUES(?, ?, DEFAULT)
ON CONFLICT(id) DO UPDATE SET
    id = excluded.id, name = excluded.name;

Exportar dados do Hologres

Exportar para um arquivo local

Os dois métodos abaixo estão disponíveis apenas no cliente PostgreSQL.

Usando o meta-comando \copy (psql)

-- Create and populate a table
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');

-- Export to a local file
\COPY (SELECT * FROM copy_to_local) TO '/root/localfile.txt';

Usando redirecionamento de stdout (psql)

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

Exportar para Object Storage Service (OSS)

Use o programa hg_dump_to_oss com COPY TO PROGRAM para exportar dados do Hologres para um bucket do OSS. Cada exportação é limitada a 5 GB.

Pré-requisitos

Apenas superusuários e usuários com a função pg_execute_server_program podem executar o hg_dump_to_oss. Conceda a função da seguinte forma:

-- Simple permission model (SPM)
CALL spm_grant('pg_execute_server_program', '<Alibaba Cloud account ID, email address, or RAM user account>');

-- Standard PostgreSQL authorization model
GRANT pg_execute_server_program TO <account>;

Sintaxe

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);
Importante

O parâmetro DirName não pode começar com / ou \.

Parâmetros

Parâmetro

Descrição

Exemplo

query

Instrução SELECT cujos resultados serão exportados.

SELECT * FROM dual;

AccessKeyId

AccessKey ID. Armazene em uma variável de ambiente para evitar expor credenciais.

AccessKeySecret

AccessKey secret. Armazene em uma variável de ambiente.

Endpoint

Endpoint de rede clássica do bucket OSS. Use o endpoint de rede clássica, não o endpoint público ou VPC. Encontre-o na página de detalhes do bucket ou em Regiões e endpoints do OSS.

oss-cn-beijing-internal.aliyuncs.com

BucketName

Nome do bucket OSS.

dummy_bucket

DirName

Caminho do diretório OSS. Não pode começar com / ou \.

testdemo/

FileName

(Opcional) Nome do arquivo de saída. Não pode conter: `` ; # '

? ~ < ( ) " $ \ { } [ ] & * \n \r ``.

file_name

BatchSize

Linhas processadas por lote. Padrão: 1000.

5000

DELIMITER

Separador de campos no arquivo de saída. Padrão: tabulação (\t).

,

Exemplos

-- Export from a Hologres internal table to 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 ',';

-- Export from a Hologres foreign table to 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);

-- Export to an OSS bucket in a different region
-- (e.g., from a Hologres instance in China (Hangzhou) to an OSS bucket in China (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);

Solução de problemas

Erro

Causa

Solução

ERROR: syntax error at or near ")" LINE 1: COPY (select 1,2,3 from ) TO PROGRAM 'hg_dump_to_oss2 --Acce...

O parâmetro query contém uma instrução SQL inválida.

Corrija a sintaxe da consulta.

DETAIL: child process exited with exit code 255

O endpoint do OSS usa o tipo de rede incorreto.

Use o endpoint de rede clássica do bucket OSS.

DETAIL: command not found

O argumento PROGRAM não está definido como hg_dump_to_oss.

Corrija o nome do programa.

DETAIL: child process exited with exit code 101

AccessKeyId inválido.

Use um AccessKey ID válido.

DETAIL: child process exited with exit code 102

AccessKeySecret inválido.

Use o AccessKey secret correto.

DETAIL: child process exited with exit code 103

Endpoint inválido.

Use o endpoint de rede clássica para o bucket OSS.

DETAIL: child process exited with exit code 104

BucketName inválido.

Verifique o nome do bucket.

DETAIL: child process exited with exit code 105

Falta um parâmetro obrigatório.

Verifique se todos os parâmetros necessários foram especificados.

ERROR: program "hg_dump_to_oss ..." failed DETAIL: child process exited with exit code 255

A instância Hologres não consegue alcançar a rede do OSS.

Mude para o endpoint de rede clássica. Para detalhes sobre endpoints, consulte Regiões e endpoints do OSS.

Exportar de um cliente JDBC usando 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();
        // Store credentials in environment variables to avoid hardcoding them
        props.setProperty("user", "AAA");     // AccessKey ID
        props.setProperty("password", "BBB"); // AccessKey secret
        return DriverManager.getConnection(url, props);
    }

    /**
     * Streams a Hologres query result into a local file via COPY TO STDOUT.
     *
     * @param connection  Active JDBC connection
     * @param filePath    Destination file path
     * @param SQL_Query   SELECT statement to export
     * @return Path of the written file
     */
    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;
    }
}

Próximos passos