Hologres にデータをロードするには COPY FROM STDIN を、エクスポートするには COPY TO STDOUT を使用します。Hologres は、標準の PostgreSQL の COPY 構文を拡張し、Hologres 固有の 2 つのパラメーター、STREAM_MODE (固定コピーモード) と ON_CONFLICT (プライマリーキー競合ポリシー) を追加しています。
すべての COPY 文は、PostgreSQL クライアントで実行する必要があります。接続の詳細については、「PostgreSQLクライアント」をご参照ください。
COPY 操作を監視するには、hologres.hg_query_log をクエリします。Hologres V3.0 以降では、各 COPY 操作で 2 つのログレコードが生成されます。1 つは COPY コマンド用、もう 1 つは内部で実行される INSERT 文用で、これらはトランザクション ID でリンクされます。詳細については、「クエリログ」をご参照ください。
制限事項
COPY FROMは、親パーティションテーブルではなく、子パーティションテーブルにのみ書き込みます。COPY FROM STDINは、Hologres V1.1.43 以降で、DEFAULT 制約または SERIAL 列を持つテーブルをサポートします。これより前のバージョンでは、これらのテーブルタイプはサポートされていません。
構文
/* データをインポート */
COPY table_name [ ( column_name [, ...] ) ]
FROM STDIN
[ [ WITH ] ( option [, ...] ) ]
/* データをエクスポート */
COPY { ( query ) }
TO STDOUT
[ [ WITH ] ( option [, ...] ) ]option には、次のいずれかを指定できます:
FORMAT format_name -- TEXT (デフォルト)、CSV、または BINARY
DELIMITER 'delimiter_character'
NULL 'null_string'
HEADER [ boolean ] -- CSV のみ
QUOTE 'quote_character' -- CSV のみ
ESCAPE 'escape_character' -- CSV のみ
FORCE_QUOTE { ( column_name [, ...] ) | * } -- CSV、COPY TO のみ
FORCE_NOT_NULL ( column_name [, ...] ) -- CSV、COPY FROM のみ
ENCODING 'encoding_name'
STREAM_MODE [ boolean ] -- Hologres 固有。COPY FROM のみ
ON_CONFLICT 'none|ignore|update' -- Hologres 固有。COPY FROM のみパラメーター
| パラメーター | 説明 |
|---|---|
table_name | データをインポートする Hologres テーブル。 |
query | 結果をエクスポートする SELECT 文。 |
STDIN | クライアントの標準入力から入力を読み取ります。 |
STDOUT | クライアントの標準出力に出力を書き込みます。 |
FORMAT | ファイル形式:TEXT (デフォルト)、CSV、または BINARY。BINARY 形式のインポートは、固定コピーモード (STREAM_MODE TRUE) でのみサポートされます。 |
DELIMITER | 列の区切り文字。デフォルト:TEXT の場合はタブ (\t)、CSV の場合はカンマ (,)。例:DELIMITER AS ','。 |
NULL | NULL 値を表す文字列。デフォルト:TEXT の場合は \N、CSV の場合は引用符で囲まれていない空の文字列。BINARY ではサポートされていません。 |
HEADER | ファイルにヘッダー行が含まれるかどうかを指定します。CSV のみ。 |
QUOTE | フィールド値を引用符で囲むために使用される 1 バイト文字。CSV のみ。デフォルト:"。 |
ESCAPE | QUOTE の値と一致する文字の前に置かれる 1 バイト文字。CSV のみ。デフォルト:QUOTE と同じ。 |
FORCE_QUOTE | 指定された列のすべての非 NULL 値を強制的に引用符で囲みます。CSV、COPY TO のみ。 |
FORCE_NOT_NULL | NULL を表す文字列を NULL ではなく、長さ 0 の文字列として扱います。CSV、COPY FROM のみ。 |
ENCODING | ファイルのエンコーディング。デフォルト:クライアントのエンコーディング。 |
STREAM_MODE | インポート時に固定コピーモードを有効にします。デフォルト:FALSE。TRUE の場合、テーブルレベルロックの代わりに、行レベルロックを使用する固定実行計画を使用します。COPY FROM のみ。 |
ON_CONFLICT | 'none'プライマリーキーの競合が発生した場合の競合ポリシー。値は、引用符なしでは大文字と小文字を区別しません。一重引用符で囲む場合は、小文字を使用します (例:)。COPY FROM のみ。詳細については、「バージョン別のON_CONFLICTの動作」をご参照ください。 |
ON_CONFLICT の値:
| 値 | 動作 | 使用するケース |
|---|---|---|
NONE | 競合時にエラーを報告します。 | 厳密なデータ整合性 — すべての行が新規である必要があります。 |
IGNORE | 競合する行をスキップします。 | 重複が想定され、既存のレコードを保持する必要がある、べき等なロード。 |
UPDATE | 競合する行を上書きします。 | 最新の値を優先するアップサートパターン。 |
バージョン別のON_CONFLICTの動作
V3.0.4 より前:
ON_CONFLICTはSTREAM_MODE TRUEの場合にのみ有効です。V3.0.4 以降:GUC パラメーター
hg_experimental_copy_enable_on_conflictが有効な場合、ON_CONFLICTはSTREAM_MODE FALSEの場合にも有効になります。STREAM_MODE FALSEの場合、UPDATEはすべての列を書き込む必要があります。V3.1.1 以降:
STREAM_MODE FALSEの場合、UPDATEは部分的な列のインポートをサポートします (hg_experimental_copy_enable_on_conflictはデフォルトで有効)。
原子性
標準の COPY (STREAM_MODE FALSE) は原子性を保証します:操作全体が成功するか、ロールバックされます。
固定コピーモード (STREAM_MODE TRUE) は、テーブルレベルロックの代わりに行レベルロックを使用するため、原子性は保証されません。行に無効なデータが含まれている場合、その行に対してのみエラーが報告され、残りの行は部分的に書き込まれるか、まったく書き込まれない可能性があります。
クエリログ
Hologres V3.0 以降では、各 COPY 操作は hologres.hg_query_log に 2 つのレコードを生成します:1 つは COPY コマンド用、もう 1 つは内部で実行される INSERT 用です。トランザクション ID を使用してこれらをリンクします:
SELECT
query_id,
query,
extended_info
FROM
hologres.hg_query_log
WHERE
extended_info ->> 'source_trx' = '<transaction_id>' -- COPY ログレコードの trans_id フィールドからトランザクション ID を取得します
ORDER BY
query_start;V3.0 より前のバージョンでは、各 COPY 操作は単一のレコードを生成します。
Hologres へのデータのインポート
PostgreSQL クライアント (stdin) からのインポート
PostgreSQL クライアントは stdin からのみ読み取ることができます。HoloWeb コンソールは stdin インポートをサポートしていません。
例 1:区切り文字付きテキストのインポート
-- ターゲットテーブルを作成
CREATE TABLE copy_test (
id int,
age int,
name text
);
-- stdin からデータをインポート
COPY copy_test FROM STDIN WITH DELIMITER AS ',' NULL AS '';
53444,24,wangming
55444,38,ligang
55444,38,luyong
\.
-- 検証
SELECT * FROM copy_test;例 2:CSVファイルのインポート
-- ターゲットテーブルを作成
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
);
-- stdin から CSV をインポート
COPY partsupp FROM STDIN WITH DELIMITER '|' CSV;
1|2|3325|771.64|final theodolites
1|25002|8076|993.49|ven ideas
\.
-- 検証
SELECT * FROM partsupp;例 3:psql を使用したローカルファイルのインポート
psql シェルのリダイレクト演算子を使用して、ローカルファイルを stdin にリダイレクトします:
psql -U <username> -p <port> -h <endpoint> -d <databasename> \
-c "COPY <table> FROM STDIN WITH DELIMITER '|' CSV;" < <filename>;| パラメーター | 説明 | 例 |
|---|---|---|
username | Alibaba Cloud アカウント:AccessKey ID。カスタムアカウント:ユーザー名 (例:BASIC$abc)。コマンドで公開されないように、AccessKey ID は環境変数に保存してください。 | — |
port | Hologres インスタンスのパブリックポート。 | 80 |
endpoint | Hologres インスタンスのパブリックエンドポイント。 | xxx-cn-hangzhou.hologres.aliyuncs.com |
databasename | Hologres データベースの名前。 | mydb |
table | ターゲットテーブルの名前。 | — |
filename | ローカルファイルのパス。 | D:\tmp\copy_test.csv |
次の例では、このコマンドを使用してローカルファイル copy_test をインポートします:

ファイルの内容は次のとおりです:
01,01,name1
02,01,name2
03,01,name3
04,01,name4インポート後、psql で結果をクエリします:

CopyManager を使用した JDBC クライアントからのインポート
Java Database Connectivity (JDBC) クライアントは、CopyManager (COPY 用の PostgreSQL JDBC ドライバーの API ラッパー) を使用して、ファイルを 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();
// 認証情報をハードコーディングしないように、環境変数に保存します
props.setProperty("user", "AAA"); // AccessKey ID
props.setProperty("password", "BBB"); // AccessKey Secret
return DriverManager.getConnection(url, props);
}
/**
* COPY FROM STDIN を使用してローカルファイルを Hologres にストリーミングします。
*
* @param connection アクティブな JDBC 接続
* @param filePath ローカルファイルのパス
* @param tableName ターゲットHologresテーブル
* @return インポートされた行数
*/
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;
}
}固定コピーモード
固定コピーモード (STREAM_MODE TRUE) は、プリコンパイルされた固定実行計画を使用して、繰り返し行われる COPY インポートを高速化します。これは、V1.3.17 から利用可能な Hologres 固有の最適化であり、インポートにのみ適用されます。他のバッチ書き込みモードとの比較については、「バッチ書き込みモードの比較」をご参照ください。内部的な仕組みについては、「固定計画によるSQL実行の高速化」をご参照ください。
列のサブセットへの書き込み — 部分更新
ON_CONFLICT UPDATE が設定されている場合で、COPY が一部の列にのみ書き込む場合、COPY リストに含まれていない列は変更されません:
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
);
-- 同等の INSERT INTO 文:
INSERT INTO t0(id, name) VALUES(?, ?)
ON CONFLICT(id) DO UPDATE SET
id = excluded.id, name = excluded.name;列のサブセットへの書き込み — デフォルト値を持つ列
COPY リストに含まれていない列に DEFAULT 値がある場合、Hologres は新規の行にのみデフォルト値を適用します。プライマリーキーで一致する既存の行は、その列については更新されません:
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
);
-- 同等の INSERT INTO 文:
-- 新しい行 (一致する id がない) の場合、age はデフォルト値に設定されます。
-- 既存の行 (一致する id がある) の場合、age は更新されません。
INSERT INTO t0(id, name, age) VALUES(?, ?, DEFAULT)
ON CONFLICT(id) DO UPDATE SET
id = excluded.id, name = excluded.name;Hologres からのデータのエクスポート
ローカルファイルへのエクスポート
以下の両方の方法は、PostgreSQL クライアントでのみ利用可能です。
\copy メタコマンドの使用 (psql)
-- テーブルを作成してデータを入力
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');
-- ローカルファイルにエクスポート
\COPY (SELECT * FROM copy_to_local) TO '/root/localfile.txt';stdout リダイレクションの使用 (psql)
psql -U <username> -p <port> -h <endpoint> -d <databasename> \
-c "COPY (SELECT * FROM <tablename>) TO STDOUT WITH DELIMITER '|' CSV;" > <filename>Object Storage Service (OSS) へのエクスポート
hg_dump_to_oss プログラムと COPY TO PROGRAM を使用して、Hologres データを OSS バケットにエクスポートします。各エクスポートは 5 GB に制限されます。
前提条件
スーパーユーザー、および pg_execute_server_program ロールを持つユーザーのみが hg_dump_to_oss を実行できます。次のようにロールを付与します:
-- 簡易権限モデル (SPM)
CALL spm_grant('pg_execute_server_program', '<Alibaba Cloud account ID, email address, or RAM user account>');
-- 標準 PostgreSQL 権限モデル
GRANT pg_execute_server_program TO <account>;構文
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 は / または \ で始めることはできません。
パラメーター
| パラメーター | 説明 | 例 | |
|---|---|---|---|
query | 結果をエクスポートする SELECT 文。 | SELECT * FROM dual; | |
AccessKeyId | AccessKey ID。認証情報が公開されないように、環境変数に保存してください。 | — | |
AccessKeySecret | AccessKey Secret。環境変数に保存してください。 | — | |
Endpoint | OSS バケットのクラシックネットワークエンドポイント。パブリックエンドポイントや VPC エンドポイントではなく、クラシックネットワークエンドポイントを使用します。バケットの詳細ページまたは「リージョンとOSSエンドポイント」で確認できます。 | oss-cn-beijing-internal.aliyuncs.com | |
BucketName | OSS バケットの名前。 | dummy_bucket | |
DirName | OSS ディレクトリのパス。/ または \ で始めることはできません。 | testdemo/ | |
FileName | (オプション) 出力ファイル名。次の文字は使用できません: ; # ' ? ~ < ( ) " $ \ { } [ ] & * \n \r 。 | file_name | |
BatchSize | バッチごとに処理される行数。デフォルト:1000。 | 5000 | |
DELIMITER | 出力ファイル内のフィールド区切り文字。デフォルト:タブ (\t)。 | , |
例
-- Hologres 内部テーブルから 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 ',';
-- Hologres 外部テーブルから 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);
-- 異なるリージョンの OSS バケットへエクスポート
-- (例:中国 (杭州) の Hologres インスタンスから中国 (北京) の OSS バケットへ)
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);トラブルシューティング
| エラー | 原因 | 解決策 |
|---|---|---|
ERROR: syntax error at or near ")" LINE 1: COPY (select 1,2,3 from ) TO PROGRAM 'hg_dump_to_oss2 --Acce... | query パラメーターに無効な SQL 文が含まれています。 | クエリ構文を修正します。 |
DETAIL: child process exited with exit code 255 | OSS エンドポイントのネットワークタイプが誤っています。 | OSS バケットのクラシックネットワークエンドポイントを使用します。 |
DETAIL: command not found | PROGRAM 引数が hg_dump_to_oss に設定されていません。 | プログラム名を修正します。 |
DETAIL: child process exited with exit code 101 | 無効な AccessKeyId。 | 有効な AccessKey ID を使用します。 |
DETAIL: child process exited with exit code 102 | 無効な AccessKeySecret。 | 正しい AccessKey Secret を使用します。 |
DETAIL: child process exited with exit code 103 | 無効な Endpoint。 | OSS バケットのクラシックネットワークエンドポイントを使用します。 |
DETAIL: child process exited with exit code 104 | 無効な BucketName。 | バケット名を確認します。 |
DETAIL: child process exited with exit code 105 | 必須パラメーターがありません。 | すべての必須パラメーターが指定されていることを確認します。 |
ERROR: program "hg_dump_to_oss ..." failed DETAIL: child process exited with exit code 255 | Hologres インスタンスが OSS ネットワークに到達できません。 | クラシックネットワークエンドポイントに切り替えます。エンドポイントの詳細については、「OSSのリージョンとエンドポイント」をご参照ください。 |
CopyManager を使用した JDBC クライアントからのエクスポート
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();
// 認証情報をハードコーディングしないように、環境変数に保存します
props.setProperty("user", "AAA"); // AccessKey ID
props.setProperty("password", "BBB"); // AccessKey Secret
return DriverManager.getConnection(url, props);
}
/**
* COPY TO STDOUT を使用して Hologres クエリの結果をローカルファイルにストリーミングします。
*
* @param connection アクティブな JDBC 接続
* @param filePath 宛先ファイルパス
* @param SQL_Query エクスポートする SELECT 文
* @return 書き込まれたファイルのパス
*/
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;
}
}次のステップ
データ型の概要 — COPY 操作でサポートされるデータ型
固定計画によるSQL実行の高速化 — 固定計画の仕組み
バッチ書き込みモードの比較 — COPY と他の書き込み方法を使い分けるタイミング