跳到主要内容
跳到主要内容

Protobuf

Not supported in ClickHouse Cloud
输入输出别名

描述

Protobuf 格式是 Protocol Buffers 格式。

此格式需要一个外部格式模式,在查询之间缓存。

ClickHouse 支持:

  • proto2proto3 语法。
  • Repeated / optional / required 字段。

示例用法

基本示例

用法示例:

SELECT * FROM test.table FORMAT Protobuf SETTINGS format_schema = 'schemafile:MessageType'
cat protobuf_messages.bin | clickhouse-client --query "INSERT INTO test.table SETTINGS format_schema='schemafile:MessageType' FORMAT Protobuf"

文件 schemafile.proto 的内容如下:

syntax = "proto3";

message MessageType {
  string name = 1;
  string surname = 2;
  uint32 birthDate = 3;
  repeated string phoneNumbers = 4;
};

为了找到表列与 Protocol Buffers 消息类型字段之间的对应关系,ClickHouse 比较它们的名称。 此比较不区分大小写,字符 _(下划线)和 .(点)被视为相等。 如果列和 Protocol Buffers 消息的字段类型不同,则应用必要的转换。

支持嵌套消息。例如,对于以下消息类型中的字段 z

message MessageType {
  message XType {
    message YType {
      int32 z;
    };
    repeated YType y;
  };
  XType x;
};

ClickHouse 尝试查找名为 x.y.z(或 x_y_zX.y_Z 等)的列。

嵌套消息适用于 嵌套数据结构 的输入或输出。

在 protobuf 模式中定义的默认值,如下面的示例,没有应用,而是使用 表默认值 代替:

syntax = "proto2";

message MessageType {
  optional int32 result_per_page = 3 [default = 10];
}

如果消息包含 oneof 并且 input_format_protobuf_oneof_presence 被设置,ClickHouse 将填写表示哪个 oneof 字段被发现的列。

syntax = "proto3";

message StringOrString {
  oneof string_oneof {
    string string1 = 1;
    string string2 = 42;
  }
}
CREATE TABLE string_or_string ( string1 String, string2 String, string_oneof Enum('no'=0, 'hello' = 1, 'world' = 42))  Engine=MergeTree ORDER BY tuple();
INSERT INTO string_or_string from INFILE '$CURDIR/data_protobuf/String1' SETTINGS format_schema='$SCHEMADIR/string_or_string.proto:StringOrString' FORMAT ProtobufSingle;
SELECT * FROM string_or_string
   ┌─────────┬─────────┬──────────────┐
   │ string1 │ string2 │ string_oneof │
   ├─────────┼─────────┼──────────────┤
1. │         │ string2 │ world        │
   ├─────────┼─────────┼──────────────┤
2. │ string1 │         │ hello        │
   └─────────┴─────────┴──────────────┘

表示存在性的列名称必须与 oneof 的名称相同。支持嵌套消息(见 basic-examples)。 允许的类型有 Int8、UInt8、Int16、UInt16、Int32、UInt32、Int64、UInt64、Enum、Enum8 或 Enum16。 Enum(以及 Enum8 或 Enum16)必须包含所有 oneof 的可能标签,并加上 0 以指示缺失,字符串表示不重要。

设置 input_format_protobuf_oneof_presence 默认情况下是禁用的。

ClickHouse 以 length-delimited 格式输入和输出 protobuf 消息。 这意味着在每条消息之前,应将其长度写为 可变宽度整数(varint)

另请参见:如何在流行语言中读写长度分隔的 protobuf 消息

使用自动生成的模式

如果您没有数据的外部 Protobuf 模式,仍然可以使用自动生成的模式以 Protobuf 格式输出/输入数据。

例如:

SELECT * FROM test.hits format Protobuf SETTINGS format_protobuf_use_autogenerated_schema=1

在这种情况下,ClickHouse 将根据表结构使用函数 structureToProtobufSchema 自动生成 Protobuf 模式。 然后使用这个模式以 Protobuf 格式序列化数据。

您还可以读取使用自动生成模式的 Protobuf 文件。在这种情况下,文件必须使用相同的模式创建:

$ cat hits.bin | clickhouse-client --query "INSERT INTO test.hits SETTINGS format_protobuf_use_autogenerated_schema=1 FORMAT Protobuf"

设置 format_protobuf_use_autogenerated_schema 默认情况下是启用的,适用于 format_schema 未设置的情况。

您还可以在输入/输出期间使用设置 output_format_schema 将自动生成的模式保存在文件中。例如:

SELECT * FROM test.hits format Protobuf SETTINGS format_protobuf_use_autogenerated_schema=1, output_format_schema='path/to/schema/schema.proto'

在这种情况下,自动生成的 Protobuf 模式将保存在文件 path/to/schema/schema.capnp 中。

删除 protobuf 缓存

要重新加载来自 format_schema_path 的 Protobuf 模式,请使用 SYSTEM DROP ... FORMAT CACHE 语句。

SYSTEM DROP FORMAT SCHEMA CACHE FOR Protobuf

格式设置