PAYATHON 2026

GridDB Rust client 插入含 TIMESTAMP 的行时为何出现类型不匹配错误?

排障赵师傅

event_time 列需要客户端的 Timestamp 值。"2026-05-06 10:30:00" 在 Rust 中是字符串,客户端不会自动将它转换为时间。写入前,需要先解析字符串,转成 Unix 毫秒时间戳,再包装为 Timestamp,最后用 gsvec! 构造包含不同字段类型的一行。客户端写入示例

为什么会出现类型不匹配

这段代码中的三个元素都是 &str:

container.put(vec!["1", "2026-05-06 10:30:00", "login"])?;

传入的是三个字符串,但容器要求的列类型依次为:

STRING, TIMESTAMP, STRING

第二个值不符合 event_time 的类型要求。连接和容器创建成功,只能说明这两步操作正常,写入值是否符合列定义还需要单独检查。

错误可能发生在编译或写入阶段。如果 put 要求接收客户端的值类型集合,普通 vec![&str, ...] 可能无法通过 Rust 编译;如果使用的封装允许传入字符串集合,写入时仍可能因第二列类型不符而失败。题目没有提供依赖版本和完整错误信息,因此无法判断具体发生在哪个阶段。

如何正确写入 TIMESTAMP

以下示例使用 griddb = "0.6.0" 的 API。该 crate 使用 griddb::griddb::Value 模块,连接工厂的路径和构造方法也与题中代码不同。如果项目使用其他版本或封装,请以实际依赖的接口为准。crate 使用说明

依赖配置如下:

[dependencies]
griddb = "0.6.0"
chrono = "0.4"

取得 container 后,用下面的代码替换原来的插入语句。示例假设输入时间是 UTC:

use chrono::NaiveDateTime;
use griddb::griddb::Value::*;
use griddb::gsvec;

// 放在已取得 container 的函数中
let dt = NaiveDateTime::parse_from_str(
    "2026-05-06 10:30:00",
    "%Y-%m-%d %H:%M:%S",
)
.expect("时间格式不正确");

let event_time = Timestamp {
    value: dt.and_utc().timestamp_millis(),
};

container
    .put(gsvec!["1", event_time, "login"])
    .expect("写入 events 失败");

这段代码修改了两处:

  • Timestamp { value: ... } 将第二个字段明确指定为 TIMESTAMP。value 是自 1970-01-01 00:00:00 UTC 起的毫秒数。
  • gsvec! 将字符串和 Timestamp 转换为客户端表示行字段的统一值类型。如果只把普通 vec! 中的字符串换成 Timestamp,集合中的元素类型就不再一致,无法满足 Rust 的要求。

示例使用 expect 简化错误处理。实际应用中,可以根据项目的错误类型传播错误或处理失败。

时间和事务需要注意什么

原始字符串不含时区,NaiveDateTime 解析后也不带时区。.and_utc() 会直接将其中的日期和时间解释为 UTC,不会自动把北京时间换算成 UTC。Chrono 文档

如果输入表示北京时间,可以改用带偏移量的字符串:

use chrono::DateTime;

let dt = DateTime::parse_from_rfc3339(
    "2026-05-06T10:30:00+08:00",
)
.expect("时间格式不正确");

let event_time = Timestamp {
    value: dt.timestamp_millis(),
};

timestamp() 返回秒数,timestamp_millis() 返回毫秒数,此处应使用后者。得到正确的 i64 毫秒数后,仍需将它包装为 Timestamp;直接传入整数,客户端会将其视为整数类型。

写入时,字段顺序应保持为 id、event_time、event_name。如果容器使用手动提交模式,成功调用 put 后还需要提交事务:

container.commit().expect("提交事务失败");

commit() 负责提交事务,无法修复字段类型不匹配的问题。

备注:内容仅供参考。