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 FROMgrava apenas em tabelas particionadas filhas, não em tabelas particionadas pai.A partir da versão Hologres V1.1.43, o
COPY FROM STDINoferece 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 |
|
|
Tabela do Hologres de destino da importação. |
|
|
Instrução SELECT cujos resultados serão exportados. |
|
|
Lê a entrada padrão do cliente. |
|
|
Grava na saída padrão do cliente. |
|
|
Formato do arquivo: |
|
|
Separador de colunas. Padrão: tabulação ( |
|
|
String que representa um valor nulo. Padrão: |
|
|
Indica se o arquivo inclui uma linha de cabeçalho. Apenas para CSV. |
|
|
Caractere de byte único usado para colocar valores de campo entre aspas. Apenas para CSV. Padrão: |
|
|
Caractere de byte único que precede uma correspondência de |
|
|
Força o uso de aspas para todos os valores não NULL nas colunas especificadas. Apenas para CSV e |
|
|
Trata strings de representação nula como strings de comprimento zero em vez de NULL. Apenas para CSV e |
|
|
Codificação do arquivo. Padrão: codificação do cliente. |
|
|
Ativa o modo de cópia fixa para importações. Padrão: |
|
|
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.: |
Valores do ON_CONFLICT:
|
Valor |
Comportamento |
Quando usar |
|
|
Reporta erro em caso de conflito. |
Integridade rigorosa dos dados — cada linha deve ser nova. |
|
|
Ignora a linha conflitante. |
Cargas idempotentes em que duplicatas são esperadas e o registro existente deve ser preservado. |
|
|
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_CONFLICTsó tem efeito quandoSTREAM_MODE TRUE.V3.0.4 e posteriores: O
ON_CONFLICTtambém entra em vigor quandoSTREAM_MODE FALSE, desde que o parâmetro GUChg_experimental_copy_enable_on_conflictesteja ativado. ComSTREAM_MODE FALSE, a opçãoUPDATEexige a gravação de todas as colunas.V3.1.1 e posteriores: Quando
STREAM_MODE FALSE, oUPDATEsuporta importações de colunas parciais (o parâmetrohg_experimental_copy_enable_on_conflictvem 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 |
|
|
Conta Alibaba Cloud: AccessKey ID. Conta personalizada: nome de usuário (ex.: |
— |
|
|
Porta pública da instância Hologres. |
|
|
|
Endpoint público da instância Hologres. |
|
|
|
Nome do banco de dados Hologres. |
|
|
|
Nome da tabela de destino. |
— |
|
|
Caminho para o arquivo local. |
|
O exemplo a seguir importa o arquivo local copy_test usando este comando:

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);
O parâmetro DirName não pode começar com / ou \.
Parâmetros
|
Parâmetro |
Descrição |
Exemplo |
|
|
|
Instrução SELECT cujos resultados serão exportados. |
|
|
|
|
AccessKey ID. Armazene em uma variável de ambiente para evitar expor credenciais. |
— |
|
|
|
AccessKey secret. Armazene em uma variável de ambiente. |
— |
|
|
|
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. |
|
|
|
|
Nome do bucket OSS. |
|
|
|
|
Caminho do diretório OSS. Não pode começar com |
|
|
|
|
(Opcional) Nome do arquivo de saída. Não pode conter: `` ; # ' |
? ~ < ( ) " $ \ { } [ ] & * \n \r ``. |
|
|
|
Linhas processadas por lote. Padrão: |
|
|
|
|
Separador de campos no arquivo de saída. Padrão: tabulação ( |
|
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 |
|
|
O parâmetro |
Corrija a sintaxe da consulta. |
|
|
O endpoint do OSS usa o tipo de rede incorreto. |
Use o endpoint de rede clássica do bucket OSS. |
|
|
O argumento |
Corrija o nome do programa. |
|
|
|
Use um AccessKey ID válido. |
|
|
|
Use o AccessKey secret correto. |
|
|
|
Use o endpoint de rede clássica para o bucket OSS. |
|
|
|
Verifique o nome do bucket. |
|
|
Falta um parâmetro obrigatório. |
Verifique se todos os parâmetros necessários foram especificados. |
|
|
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
Visão geral dos tipos de dados — Tipos de dados suportados para operações COPY
Acelerar execução SQL com plano fixo — Como funcionam os planos fixos
Comparação de modos de gravação em lote — Quando usar COPY versus outros métodos de gravação