Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

HiveText

输入 输出 别名

说明

HiveText 用于读取和写入 Apache Hive 表使用的文本序列化格式 (即 Hive 的 LazySimpleSerDe 生成的格式) 。它是一种带分隔符的文本 格式,类似于 CSV,其中字段使用 Hive 默认的 \x01 (Ctrl-A) 作为分隔符。字段分隔符 可通过 input_format_hive_text_fields_delimiter 配置。

作为输入格式使用时,数据没有表头:值会按位置映射到目标表的各列,因此列名和类型取自该表 (或显式提供的 结构) ,而不是从数据中自动推断。读取时,ClickHouse 会以尽力而为模式解析 日期和时间 (参见 date_time_input_format) , 用列默认值填充末尾省略的字段,并跳过无法 识别的字段。

在单个字段内,值会使用与 CSV 相同的转义规则进行解析,而不是使用 Hive 的嵌套分隔符。特别是,类型为 Array 的列会从带方括号的 表示形式读取 (例如 "['a','b','c']") ,而不是从由 Hive 集合分隔符 \x02 分隔的值中读取。

默认情况下,允许行包含数量不固定的字段 (参见 input_format_hive_text_allow_variable_number_of_columns) : 字段数少于表列数的行会用默认值填充缺失列,而包含额外尾随字段的行会跳过这些多余字段。

示例用法

下面的示例通过 input_format_hive_text_fields_delimiter 将默认字段分隔符改为逗号 (,) ,让输入 文件更易于阅读。

读取 HiveText 文件

假设有一个名为 hive_data.txt 的文件,其字段由逗号分隔:

hive_data.txttext
1,3
3,5,9

我们创建一个表,定义列名和类型,然后使用 FORMAT HiveText 将文件插入该表:

Querysql
CREATE TABLE test_tbl (a UInt16, b UInt32, c UInt32) ENGINE = MergeTree ORDER BY a;

INSERT INTO test_tbl FROM INFILE 'hive_data.txt'
SETTINGS input_format_hive_text_fields_delimiter = ','
FORMAT HiveText;

SELECT * FROM test_tbl;
Responseresponse
┌─a─┬─b─┬─c─┐
│ 1 │ 3 │ 0 │
│ 3 │ 5 │ 9 │
└───┴───┴───┘

请注意,第一行 1,3 只有两个字段,因此缺失的列 c 会以默认值 0 进行填充。

可变列数

在默认设置 input_format_hive_text_allow_variable_number_of_columns = 1 下, 如果某些行的字段数多于表中的列数,末尾多出的字段会被直接跳过:

hive_extras.txttext
1,2,3,4,5
6,7,8
Querysql
CREATE TABLE test_extras (a UInt16, b UInt32, c UInt32) ENGINE = MergeTree ORDER BY a;

INSERT INTO test_extras FROM INFILE 'hive_extras.txt'
SETTINGS input_format_hive_text_fields_delimiter = ','
FORMAT HiveText;

SELECT * FROM test_extras ORDER BY a;
Responseresponse
┌─a─┬─b─┬─c─┐
│ 1 │ 2 │ 3 │
│ 6 │ 7 │ 8 │
└───┴───┴───┘

改为将 input_format_hive_text_allow_variable_number_of_columns = 0 设为 0 会强制要求字段数严格一致,而当某一行的字段数少于表中的字段数时,会引发 解析异常。

输出

作为输出格式使用时,HiveText 会写入每一行,不添加任何引号: 顶层字段以字段分隔符分隔 (默认为 \x01) , 行则以行分隔符分隔 (默认为 \n,可通过 format_hive_text_rows_delimiter 配置) 。嵌套类型的值 (ArrayMapTuple) 写入时不带括号,并以对应嵌套层级的 Hive 分隔符分隔,其方式与 Hive 的 LazySimpleSerDe 相同。前三个分隔符依次为可配置的字段 分隔符、input_format_hive_text_collection_items_delimiter (默认为 \x02,用于数组元素、映射条目和元组元素) 以及 input_format_hive_text_map_keys_delimiter (默认为 \x03, 用于分隔映射键及其值) ;更深层级默认使用连续的控制 字符 (\x04\x05,依此类推,最多八个层级) 。如果嵌套类型树足够深, 需要使用超过这八个层级的分隔符,则会因 NOT_IMPLEMENTED 异常被拒绝,因为 Hive 的 LazySimpleSerDe 同样没有对应的 分隔符。没有自然的 Hive 文本表示形式的数据类型不支持输出,并会引发 NOT_IMPLEMENTED 异常。这包括 AggregateFunctionDynamicVariantLowCardinalityObject,以及以数值类型为底层类型的 EnumTimeTime64Interval —— Hive 没有与后者对应的类型, 因此会拒绝它们,而不会将其写为原始的底层 数值。宽整数类型 Int128UInt128Int256UInt256 也会因相同原因被拒绝:Hive 支持的最大整数类型是 BIGINT (64 位) , 即使是最大精度为 38 的 Hive DECIMAL 也无法容纳其 值域。同样,精度超过 38 的 Decimal 值 (即 Decimal256) 超出 Hive DECIMAL 的最大精度,因此会被拒绝。 同样,Map 的键必须是基本类型:Hive 将映射声明为 MAP<primitive_type, data_type>,因此键类型为 ArrayMapTupleMap (ClickHouse 允许此类映射) 会因 NOT_IMPLEMENTED 异常被拒绝,因为没有任何 Hive schema 能够将此类值 读回。空映射字面量 map() 也会因相同原因被拒绝:其类型 为 Map(Nothing, Nothing),而 Nothing 不是 Hive MAP<key_type, data_type> 声明中可使用的类型。所有这些检查都会在 写入任何行之前,预先针对声明的列类型执行:如果查询的结果头在其类型树的任何位置包含不受支持的类型, 即使实际值永远不会触及不受支持的 序列化,查询也会被拒绝 (例如,仅包含 NULL 值的不受支持类型 Nullable, 或元素类型不受支持的空 Array/Map) , 因为文件声明的 schema 仍无法对应任何 Hive 表。

DateDate32DateTimeDateTime64 始终以纯文本 Hive 日期和时间戳格式 (yyyy-MM-ddyyyy-MM-dd HH:mm:ss[.fffffffff]) 写入, 不受 date_time_output_format 设置影响,因此即使该设置为 unix_timestampiso,输出仍可由 Hive 解析。

出于相同原因,Bool 值始终写为 true/false, 不受 bool_true_representationbool_false_representation 设置影响,且 NULL 值始终写为 Hive 的默认空值序列 \N,不受 format_csv_null_representation 设置影响。这确保无论这些通用文本设置如何,输出都可由 Hive 的 LazySimpleSerDe 读取。 相应地,HiveText 输入格式始终将 \N 读取为 NULL,同样不受 format_csv_null_representation 设置影响,因此顶层标量的往返转换不依赖于该设置。

非有限 Float32Float64 值会采用 Hive 的 Java 拼写形式写入: NaNInfinity-Infinity,而不是 ClickHouse 通常使用的 nan/inf/-inf 标记,以便 Hive 的 FLOAT/DOUBLE 解析器将其读回为相同的值, 而非 NULL

Querysql
SELECT '20240305', tuple(123567, 'e01001', map('action1', 33333, 'act2', 5555)) FORMAT HiveText;

格式设置

设置 说明 默认值
input_format_hive_text_fields_delimiter Hive Text File 中字段之间的分隔符 \x01
input_format_hive_text_collection_items_delimiter Hive Text File 中集合 (Array 或 map) 元素之间的分隔符。由输出格式使用;可接受,但当前在解析时未使用。 \x02
input_format_hive_text_map_keys_delimiter Hive Text File 中一对 map 键/值之间的分隔符。由输出格式使用;可接受,但当前在解析时未使用。 \x03
input_format_hive_text_allow_variable_number_of_columns 忽略 Hive Text 输入中的多余列 (如果文件中的列数超过预期) ,并将缺失字段视为默认值 1
format_hive_text_rows_delimiter Hive Text 输出中每行末尾的分隔符 \n
Navigation