自 Hologres V4.1 版本起,支持通过 EXTERNAL_FILES 函数直接查询、导入和导出 OSS(对象存储服务)上的结构化数据文件,无需创建外部表。本文介绍使用前提、语法、参数、示例及使用限制。
概述
EXTERNAL_FILES 函数用于直接查询、导入和导出 OSS 上的结构化数据文件,无需创建外部表即可进行数据操作。主要支持以下场景:
-
数据查询:直接查询 OSS 上的 CSV、Parquet、ORC 格式文件。
-
数据导入:将 OSS 上的数据导入到 Hologres 内表。
-
数据导出:将 Hologres 表中的数据导出到 OSS。
使用前提
版本要求
实例需为 Hologres V4.1 及以上版本。若实例为 V4.1 以下版本,请参见实例升级。
权限配置
EXTERNAL_FILES 仅支持 RAM 子账号或主账号使用,暂不支持自定义账号。使用前需完成以下配置:EXTERNAL_FILES 通过 RAM 角色访问 OSS,因此需先创建角色并授权给 Hologres 服务,再为角色授予 OSS 相关权限。
创建角色
-
登录阿里云 RAM 访问控制管控台,进入角色列表,点击创建角色。
-
在弹窗中选择信任主体类型为「云服务」,信任主体名称选择「实时数仓 Hologres」。
-
填写角色名称并完成创建。
配置 OSS 访问权限
为 RAM 角色配置 OSS 权限:
-
读取数据:授予
AliyunOSSReadOnlyAccess权限。 -
写入数据:授予
AliyunOSSFullAccess权限。
授予运行 SQL 的用户 GrantAssumeRole 权限
若执行用户非主账号,需先授予该用户 GrantAssumeRole 权限:
-
在 RAM 访问控制中创建权限策略(权限策略 → 创建权限策略 → 脚本编辑),粘贴以下内容,其中
Role_ARN需与 EXTERNAL_FILES 使用的role_arn相同。如何查找 Role_ARN 请参见RAM 角色与 STS 常见问题。
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": "hologram:GrantAssumeRole",
"Resource": "<RoleARN>"
}
]
}
然后将该策略授权给运行查询的用户(RAM 用户:用户 → 权限管理 → 新增授权;RAM 角色:角色 → 权限管理 → 新增授权)。
语法说明
查询数据
SELECT * FROM EXTERNAL_FILES(
path = 'oss://bucket/path',
format = 'csv|parquet|orc',
oss_endpoint = 'oss_endpoint',
role_arn = 'acs:ram::xxx:role/xxx'
[, 其他参数...]
) [AS (col1 type1, col2 type2, ...)]
导入数据
INSERT INTO target_table
SELECT * FROM EXTERNAL_FILES(
path = 'oss://bucket/path',
format = 'csv|parquet|orc',
oss_endpoint = 'oss_endpoint',
role_arn = 'acs:ram::xxx:role/xxx'
[, 其他参数...]
) [AS (col1 type1, col2 type2, ...)]
导出数据
INSERT INTO EXTERNAL_FILES(
path = 'oss://bucket/path',
format = 'csv',
oss_endpoint = 'oss_endpoint',
role_arn = 'acs:ram::xxx:role/xxx'
[, 其他参数...]
) SELECT * FROM source_table;
参数说明
通用参数
|
参数名 |
说明 |
是否必填 |
示例 |
|
|
文件路径,支持目录和文件;可指定多个路径(逗号分隔);支持 |
是 |
|
|
|
文件格式。查询支持 |
是 |
|
|
|
OSS 经典网络访问域名,详见OSS 地域与端点。 |
否 |
|
|
|
阿里云 RAM 角色的 ARN。 |
否 |
|
读取参数
|
参数名 |
说明 |
是否必填 |
示例 |
|
|
推断 Schema 时读取的最大文件数,默认 5。 |
否 |
|
|
|
推断 Schema 时文件的排列顺序,默认新文件在前。 |
否 |
|
|
|
是否跳过 CSV 首行(作为表头),默认 |
否 |
|
|
|
CSV 列分隔符,默认为逗号。 |
否 |
|
写入参数
|
参数名 |
说明 |
是否必填 |
示例 |
|
|
单个输出文件大小(MB),默认 10。 |
否 |
|
|
|
是否只写入单个文件,默认 |
否 |
|
使用示例
示例 1:查询 CSV 文件
查询 OSS 上的 CSV 文件,自动推断 Schema:
SELECT * FROM EXTERNAL_FILES(
path = 'oss://mybucket/data/',
format = 'csv',
csv_skip_header = 'true',
csv_delimiter = ',',
oss_endpoint = 'oss-cn-hangzhou-internal.aliyuncs.com',
role_arn = 'acs:ram::123456789:role/hologres-role'
);
查询 CSV 文件,手动指定 Schema:
SELECT * FROM EXTERNAL_FILES(
path = 'oss://mybucket/data/',
format = 'csv',
csv_skip_header = 'true',
oss_endpoint = 'oss-cn-hangzhou-internal.aliyuncs.com',
role_arn = 'acs:ram::123456789:role/hologres-role'
) AS (id int, name text, amount decimal(10,2));
示例 2:查询 Parquet 文件
SELECT * FROM EXTERNAL_FILES(
path = 'oss://mybucket/parquet_data/',
format = 'parquet',
oss_endpoint = 'oss-cn-hangzhou-internal.aliyuncs.com',
role_arn = 'acs:ram::123456789:role/hologres-role'
);
示例 3:查询 ORC 文件
SELECT * FROM EXTERNAL_FILES(
path = 'oss://mybucket/orc_data/',
format = 'orc',
oss_endpoint = 'oss-cn-hangzhou-internal.aliyuncs.com',
role_arn = 'acs:ram::123456789:role/hologres-role'
);
示例 4:导入数据到 Hologres 表
-- 创建目标表
CREATE TABLE orders (
order_id int,
customer_name text,
amount decimal(10,2),
PRIMARY KEY(order_id)
);
-- 从 OSS 导入数据
INSERT INTO orders
SELECT * FROM EXTERNAL_FILES(
path = 'oss://mybucket/orders/',
format = 'csv',
csv_skip_header = 'true',
oss_endpoint = 'oss-cn-hangzhou-internal.aliyuncs.com',
role_arn = 'acs:ram::123456789:role/hologres-role'
) AS (order_id int, customer_name text, amount decimal(10,2));
示例 5:导出数据到 OSS
导出为多个文件:
INSERT INTO EXTERNAL_FILES(
path = 'oss://mybucket/export/',
format = 'csv',
oss_endpoint = 'oss-cn-hangzhou-internal.aliyuncs.com',
role_arn = 'acs:ram::123456789:role/hologres-role',
target_file_size_mb = '100'
) SELECT * FROM orders;
导出为单个文件:
INSERT INTO EXTERNAL_FILES(
path = 'oss://mybucket/export/',
format = 'csv',
oss_endpoint = 'oss-cn-hangzhou-internal.aliyuncs.com',
role_arn = 'acs:ram::123456789:role/hologres-role',
single_file = 'true'
) SELECT * FROM orders;
示例 6:使用 Serverless 资源组
SET hg_computing_resource = 'serverless';
SELECT * FROM EXTERNAL_FILES(
path = 'oss://mybucket/data/',
format = 'csv',
oss_endpoint = 'oss-cn-hangzhou-internal.aliyuncs.com',
role_arn = 'acs:ram::123456789:role/hologres-role'
);
Schema 推断规则
自动推断 Schema
当不使用 AS 子句指定 Schema 时,系统会自动推断:
-
Parquet/ORC:根据文件元数据自动推断。
-
带表头的 CSV:根据首行表头及数据内容推断。
-
不带表头的 CSV:要求所有文件 Schema 一致。
推断时会扫描 schema_deduce_file_num 指定数量的文件,取所有文件 Schema 的并集。
Schema 推断行为
|
场景 |
处理方式 |
|
Schema 中的列在文件中不存在 |
自动填充 NULL |
|
文件中的列在 Schema 中不存在 |
自动忽略该列 |
|
列类型不匹配但可转换 |
自动类型转换 |
|
列类型不匹配且无法转换 |
返回 NULL |
类型映射
EXTERNAL_FILES 读取 ORC/Parquet 时,会将文件类型映射为 PostgreSQL 类型,对应关系如下。不支持的类型见各表下方说明。
ORC 类型映射
ORC 类型 |
PostgreSQL 类型 |
|---|---|
BOOLEAN | BOOLEAN |
TINYINT / SMALLINT | SMALLINT |
INT | INTEGER |
BIGINT | BIGINT |
FLOAT | REAL |
DOUBLE | DOUBLE PRECISION |
DECIMAL(p, s) | DECIMAL(p, s) |
STRING | TEXT |
VARCHAR(n) | VARCHAR(n) |
CHAR(n) | CHAR(n) |
BINARY | BYTEA |
DATE | DATE |
TIMESTAMP | TIMESTAMP WITHOUT TIME ZONE |
TIMESTAMP WITH LOCAL TIMEZONE | TIMESTAMP WITH TIME ZONE |
LIST | 数组(pg_type[]) |
ORC 的 UNION、STRUCT、MAP 类型不支持。
Parquet 类型映射
Parquet 物理类型 |
Parquet 逻辑类型 |
PostgreSQL 类型 |
|---|---|---|
BOOLEAN | — | BOOLEAN |
INT32 | — | INTEGER |
INT32 | DATE | DATE |
INT32 | DECIMAL(p, s) | DECIMAL(p, s) |
INT64 | — | BIGINT |
INT64 | TIMESTAMP_MILLIS / MICROS | TIMESTAMP / TIMESTAMPTZ |
INT64 | DECIMAL(p, s) | DECIMAL(p, s) |
FLOAT | — | REAL |
DOUBLE | — | DOUBLE PRECISION |
BYTE_ARRAY | — | BYTEA |
BYTE_ARRAY | STRING | TEXT |
BYTE_ARRAY | JSON / BSON | JSONB |
BYTE_ARRAY | ENUM | TEXT |
FIXED_LEN_BYTE_ARRAY | DECIMAL(p, s) | DECIMAL(p, s) |
FIXED_LEN_BYTE_ARRAY | UUID | UUID |
LIST | LIST | 数组(pg_type[]) |
Parquet 的 STRUCT、MAP 类型不支持。
使用限制
-
导出格式:目前导出仅支持 CSV 格式。
-
递归查找:不支持递归查找子目录。
-
不支持的类型:ORC 的 UNION/STRUCT/MAP、Parquet 的 STRUCT/MAP 不支持。
常见问题
Q:导出数据时提示权限不足怎么办?
A:请确保 RAM 角色已授予 AliyunOSSFullAccess 权限。
Q:如何控制导出文件的大小?
A:使用 target_file_size_mb 参数指定单个文件大小。如需更精细控制,可调整 hg_experimental_query_batch_size 参数。