Use COPY FROM STDIN para carregar dados no Hologres e COPY TO STDOUT para exportá-los. O Hologres estende a sintaxe padrão COPY do PostgreSQL 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 de conexão, consulte PostgreSQL client.
Para monitorar as operações COPY, consulte hologres.hg_query_log. A partir do Hologres V3.0, 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
COPY FROMgrava apenas em tabelas filho particionadas, e não em tabelas pai particionadas.O
COPY FROM STDINsuporta tabelas com restrição DEFAULT ou colunas SERIAL a partir do Hologres V1.1.43. As 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 [, ...] ) ]
Em que option pode ser um dos seguintes valores:
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 de dados. |
|
|
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: tab ( |
|
|
String que representa um valor nulo. Padrão: |
|
|
Indica se o arquivo inclui uma linha de cabeçalho. Apenas para CSV. |
|
|
Caractere de um único byte usado para delimitar valores de campo com aspas. Apenas para CSV. Padrão: |
|
|
Caractere de um único byte que precede uma ocorrência de |
|
|
Força o uso de aspas em todos os valores não nulos 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: a codificação do cliente. |
|
|
Ativa o modo de cópia fixa para importações. Padrão: |
|
|
Política de conflito em caso de colisão de chave primária. Os valores sem aspas não diferenciam maiúsculas de minúsculas; com aspas simples, use letras minúsculas (por exemplo, |
Valores de ON_CONFLICT:
|
Valor |
Comportamento |
Quando usar |
|
|
Reporta um erro em caso de conflito. |
Integridade rigorosa dos dados: cada linha deve ser nova. |
|
|
Ignora a linha em conflito. |
Operações de carga idempotentes nas quais duplicatas são esperadas e o registro existente deve ser preservado. |
|
|
Sobrescreve a linha em conflito. |
Padrões de upsert nos quais o valor mais recente deve prevalecer. |
Comportamento do ON_CONFLICT por versão
Antes da V3.0.4: o
ON_CONFLICTé aplicado apenas quandoSTREAM_MODE TRUE.V3.0.4 e posteriores: o
ON_CONFLICTtambém é aplicado quandoSTREAM_MODE FALSE, com o parâmetro GUChg_experimental_copy_enable_on_conflictativado. QuandoSTREAM_MODE FALSE, oUPDATEexige a inclusão de todas as colunas.V3.1.1 e posteriores: quando
STREAM_MODE FALSE, oUPDATEsuporta importações de colunas parciais (hg_experimental_copy_enable_on_conflicté ativado por padrão).
Atomicidade
A operação COPY padrão (STREAM_MODE FALSE) garante atomicidade: toda a operação é concluída com sucesso ou é revertida.
O modo de cópia fixa (STREAM_MODE TRUE) usa um bloqueio no nível de linha em vez de um bloqueio no nível de tabela; portanto, não há garantia de atomicidade. Se uma linha contiver dados inválidos, o sistema reporta um erro apenas para essa linha — as linhas restantes podem ser gravadas parcialmente ou ignoradas.
Log de consultas
A partir do Hologres V3.0, 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 pelo 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 do stdin. O console do 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 o 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 do Alibaba Cloud: AccessKey ID. Conta personalizada: nome de usuário (por exemplo, |
— |
|
|
Porta pública da instância do Hologres. |
|
|
|
Endpoint público da instância do Hologres. |
|
|
|
Nome do banco de dados do Hologres. |
|
|
|
Nome da tabela de destino. |
— |
|
|
Caminho para o arquivo local. |
|
O exemplo a seguir importa o arquivo local copy_test com 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
Os clientes Java Database Connectivity (JDBC) podem usar o CopyManager — wrapper de API do driver JDBC do PostgreSQL para COPY — para transmitir arquivos ao 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. Essa é uma otimização específica do Hologres, disponível desde a V1.3.17, e aplica-se apenas a importações. Para comparar com outros modos de gravação em lote, consulte Comparison of batch write modes. Para entender o mecanismo subjacente, consulte Accelerate SQL execution with fixed plan.
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 não incluídas na lista do COPY não sofrem modificação:
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
Quando uma coluna não incluída na lista do COPY possui um valor DEFAULT, o Hologres aplica o valor padrão apenas a novas linhas. O sistema não atualiza as linhas existentes correspondentes à chave primária nessa coluna:
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.
Usar o metacomando \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';
Usar 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 o 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. O limite de cada exportação é de 5 GB.
Pré-requisitos
Somente 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);
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-o em uma variável de ambiente para evitar a exposição de credenciais. |
— |
|
|
|
AccessKey secret. Armazene-o em uma variável de ambiente. |
— |
|
|
|
Endpoint de rede clássica do bucket do OSS. Use o endpoint de rede clássica, em vez do endpoint público ou de VPC. Encontre-o na página de detalhes do bucket ou em Regions and OSS endpoints. |
|
|
|
|
Nome do bucket do OSS. |
|
|
|
|
Caminho do diretório do 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: tab ( |
|
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 do 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 do OSS. |
|
|
|
Verifique o nome do bucket. |
|
|
Um parâmetro obrigatório está ausente. |
Verifique se todos os parâmetros obrigatórios estão especificados. |
|
|
A instância do Hologres não consegue acessar a rede do OSS. |
Mude para o endpoint de rede clássica. Para obter detalhes sobre endpoints, consulte OSS regions and endpoints. |
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
Data types overview — Tipos de dados compatíveis com as operações COPY
Accelerate SQL execution with fixed plan — Como os planos fixos funcionam
Comparison of batch write modes — Quando usar o COPY em comparação com outros métodos de gravação