Field property(字段属性)

Tableau field property 使用指南。

概览

选项类型说明
uniquebool检查字段唯一性。
默认值:false。对于 map(或 KeyedList)的 key,默认值会自动推断。
rangestring格式:"left,right"。例如:"1,10""1,~""~,10"
range 的不同含义:
- 数字:值范围。
- 字符串:UTF-8 码点数量。
referstring格式:"SheetName(SheetAlias).ColumnName"
确保该字段的值在另一个 sheet 的列值空间中。多个 refer 用逗号分隔。
sequenceint64确保该字段的值是一个从指定值开始的序列。
defaultstring如果单元格为空,则使用此默认值。
fixedbool自动检测水平 list/map 的固定大小。
默认值:false
sizeuint32指定水平 list/map 的固定大小。
formForm指定 incell struct 的单元格数据格式。
- FORM_TEXT
- FORM_JSON
json_namestring指定字段的自定义 JSON 名称,替代 proto 字段名的 lowerCamelCase 形式。
presentbool如果 present 为 true,则必须显式填写单元格数据。
默认值:false
optionalbool该字段是否为可选(字段名可缺失)。
patchPatch字段 patch 类型。
- PATCH_REPLACE
- PATCH_MERGE
sepstring字段级分隔符。
subsepstring字段级子分隔符。
patternstring指定 scalar、list 元素和 map value 的模式。
validatestring适用于 scalar 和 well-known 类型的 protovalidate 字段级校验规则。
例如:"string:{max_len:10}""int32:{gt:0 lte:100}""cel_expression:\"this >= timestamp('2024-01-01T00:00:00Z')\""
validate_complexstring适用于复合类型(list/map)的 protovalidate 字段级校验规则。
例如:"repeated:{min_items:1}""map:{min_pairs:1}"
validate_messagestring适用于字段所嵌套 message 的 protovalidate message 级校验规则。
例如:"cel_expression:\"this.start_time < this.end_time\""

选项 unique

选项 unique 可在 field property 中指定为 truefalse,用于检查 list/map 元素中任意 scalar 字段的唯一性。

  • 如果显式设置 uniquetrue,当出现重复 key 时 tableau 会报错。
  • 如果显式设置 uniquefalse,则不进行检查。

Map(或 KeyedList)的 key

Tableau 会自动推断 map(或 KeyedList)key 的 unique 是否为 true。

规则是:如果 map 的 value 类型(或 KeyedList 元素类型)没有相同布局(垂直/水平)的子 map/list 字段,则 key 必须唯一。

因此大多数情况下不需要显式配置。

通用 scalar 字段

如果将通用 scalar 字段的属性 unique 指定为 true,则 tableau 会检查该字段在 map 或 list 中的唯一性。

选项 range

[!WARNING] 当单元格数据为空(未填写)时,此检查将被跳过。若需对空单元格也强制执行检查,请将选项 present 设置为 true

选项 range 的格式为:"left,right"(左右均为闭区间)。

range 的不同含义:

  • 数字:值范围,例如:"1,10""1,~""~,10"
  • 字符串:UTF-8 码点数量。
  • list:list 的长度。
  • map:map 的长度。

选项 refer

选项 refer 类似于 SQL 中的外键(FOREIGN KEY)约束,用于防止破坏表之间关联的操作。但 tableau 的 refer 可以引用任意 sheet 的列(不限于 map key 列),并且支持多个 refer(逗号分隔)。它用于确保该字段的值至少在其他某个 sheet 的列值空间(即 message 的字段值空间)中存在。

格式:"SheetName(SheetAlias).ColumnName[,SheetName(SheetAlias).ColumnName]..."

示例:

  • map<uint32, Reward>|{refer:"ItemConf.ID"}:无别名的单 refer,sheet 名即为生成的 protobuf message 名。
  • map<uint32, Reward>|{refer:"ItemConf.ID,EquipConf.ID"}:无别名的多 refer,sheet 别名即为生成的 protobuf message 名。
  • map<uint32, Reward>|{refer:"Sheet1(ItemConf).ID"}:有别名的单 refer,sheet 别名即为生成的 protobuf message 名。

选项 sequence

选项 sequence 用于确保该字段的值是一个从指定值开始的序列,可用于任意字段,包括嵌套 list/map 中的字段。

示例:

  • map<uint32, Item>|{sequence:1}:该 map key 必须遵循从值 1 开始的序列规则。
  • int32|{sequence:1}:父级 list/map 的元素必须遵循从值 1 开始的序列规则。

选项 default

如果设置了选项 default,则当单元格为空时使用该值作为默认值。

选项 fixed

如果将选项 fixed 设置为 true,则自动检测水平 list/map 的固定大小。

示例:

选项 size

选项 size 用于指定水平 list/map 的固定大小。

示例:

选项 form

选项 form 用于指定 incell struct 的单元格数据格式。

可指定两种格式:

详细示例请参考 高级 predefined incell struct

选项 json_name

默认情况下,JSON 名称由字段的 proto 名称转换为 camelCase 得到。现在可以通过 json_name prop 选项显式指定。

例如,HelloWorld.xlsx 中的 worksheet ItemConf

IDRarity_1SpecialEffect_2
map<int32, Item>int32|{json_name:“rarity_1”}int32|{json_name:“specialEffect_2”}
Item’s IDItem’s rarity.Item’s special effect.
110101
220102
330103

选项 present

如果将选项 present 设置为 true,则单元格数据不能为空,必须显式填写,否则会报错。

选项 optional

指定该字段是否为可选(字段名可缺失)。

如果设置为 true,则:

  • 表格格式(Excel/CSV):字段的列可以缺失。
  • 文档格式(XML/YAML):字段名可以缺失。

选项 patch

参见 选项 Patch 中的字段级 patch。

选项 sep

字段级分隔符,用于分隔:

  • incell list 元素(scalar 或 struct)。
  • incell map 元素

如果未设置,将使用 metasheet 中的sheet 级 sep。

选项 subsep

字段级子分隔符,用于分隔:

  • 每个 incell map 元素的键值对。
  • 每个 incell struct list 元素的结构体字段。

如果未设置,将使用 metasheet 中的sheet 级 subsep。

选项 pattern

指定 scalar 字段、list 元素和 map value 的模式。

Wellknown version 字段

[!NOTE] 使用案例请参考 Wellknown types: Version

指定当前单元格的点分十进制模式。每个十进制数的范围从 0 到模式对应部分的最大值(MAX)。

默认模式:255.255.255

选项 validate

Tableau 集成了 protovalidate, 可以直接在表格字段属性中声明校验规则。这些规则会被编译为生成 .proto 文件中 字段上的 (buf.validate.field) 选项,并在 tableau 生成配置时强制执行。支持 CEL 表达式以及 protovalidate 提供 的标准规则、predefined 规则和自定义(custom)规则。

选项 validate 用于指定 scalar 和 well-known 类型 (例如 int32stringboolgoogle.protobuf.Timestampgoogle.protobuf.Duration 等) 的字段级校验规则。其值为 buf.validate.FieldRulesprotobuf text format 表示。

示例:

  • int32|{validate:"int32:{gt:0 lte:100}"}:值必须在 (0, 100] 范围内。
  • string|{validate:"string:{min_len:1 max_len:20}"}:字符串长度必须在 [1, 20] 范围内。
  • uint32|{validate:"uint32:{gt:0}"}:值必须大于 0
  • datetime|{validate:"timestamp:{lt:{seconds:1893456000}}"}:时间戳必须早于 2030-01-01T00:00:00Z(Unix 秒数 1893456000)。
  • datetime|{validate:"cel_expression:\"this >= timestamp('2024-01-01T00:00:00Z')\""}:自定义 CEL 表达式。
  • int32|{validate:"int32:{[protoconf.is_zero]:true}"}:使用通过 proto 扩展定义的 自定义规则

[!WARNING] 避免将字段值与当前时间进行比较(例如 timestamp:{gt_now:true} / lt_now:true,或在 CEL 表达式中引用 now)。配置是在构建时生成并校验的, 依赖“当前时间”的规则会因生成时刻不同而时而通过、时而失败,导致配置导出 不稳定且不可复现。建议使用固定的边界(绝对时间戳),或在同一条记录的多个 字段之间施加约束(例如 start_time < end_time)。

例如,HelloWorld.xlsx 中的 worksheet ItemConf

IDNameScore
map<uint32, Item>|{validate:“uint32:{gt:0}”}string|{validate:“string:{min_len:1 max_len:20}”}int32|{validate:“int32:{gt:0 lte:100}”}
Item IDItem NameItem Score
1sword80
2shield95

生成结果:

hello_world.proto
// --snip--
import "buf/validate/validate.proto";

message ItemConf {
  option (tableau.worksheet) = {name:"ItemConf"};

  map<uint32, Item> item_map = 1 [(tableau.field) = {key:"ID" layout:LAYOUT_VERTICAL}];
  message Item {
    uint32 id = 1 [(tableau.field) = {name:"ID"}, (buf.validate.field) = {uint32:{gt:0}}];
    string name = 2 [(tableau.field) = {name:"Name"}, (buf.validate.field) = {string:{min_len:1 max_len:20}}];
    int32 score = 3 [(tableau.field) = {name:"Score"}, (buf.validate.field) = {int32:{gt:0 lte:100}}];
  }
}

选项 validate_complex

选项 validate_complex 用于指定复合类型(即 list/map)的字段级校验 规则——即对容器本身(而非其元素)施加的规则。其值为 buf.validate.FieldRulesrepeatedmap 字段已设置)的 text format 表示。

示例:

  • map<uint32, Item>|{validate_complex:"map:{min_pairs:1}"}:map 必须至少包含一个条目。
  • []string|{validate_complex:"repeated:{min_items:1}"}:list 必须至少包含一个元素。
  • []string|{validate_complex:"repeated:{[protoconf.min_items_three]:true}"}:使用自定义规则。

[!NOTE] validate 用于元素/值类型自身的规则,validate_complex 用于容器的规则。 这两个选项可以在同一个字段上同时使用。

选项 validate_message

选项 validate_message 用于指定字段所嵌套 message 的 message 级校验规则。 通常在字段的值类型为子 message(例如 struct,或 map/list 的 value 类型)时使用, 用于通过 CEL 表达式对 message 的多个字段进行交叉校验。其值为 buf.validate.MessageRules 的 text format 表示。

示例:

  • map<uint32, Item>|{validate_message:"cel_expression:\"this.value <= 0 || this.name != ''\""}:map 中每个 value(Item)都必须满足该 CEL 表达式。
  • {Timespan}datetime|{validate_message:"cel_expression:\"this.start_time < this.end_time\""}:每个 Timespan struct 都必须满足 start_time < end_time

CEL 表达式中的 this 指代被嵌套的 message 实例。