You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Kinesis Firehose动态分区:日期解析失败问题求助

Kinesis Firehose动态分区日期解析问题解决

问题背景

接收的JSON payload格式如下:

{
  "clientId": "ASGr496mndGs80oCC97mf",
  "createdAt": "2022-09-21T14:44:53.708Z",
  ...
}

已启用Firehose的「动态分区」和「内联JSON解析」,配置的分区键如下:

year 
.createdAt| strptime("%Y-%m-%dT%H:%M:%S.%fZ")| strftime("%Y")
month 
.createdAt| strptime("%Y-%m-%dT%H:%M:%S.%fZ")| strftime("%m")
day
.createdAt| strptime("%Y-%m-%dT%H:%M:%S.%fZ")| strftime("%d")
hour
.createdAt| strptime("%Y-%m-%dT%H:%M:%S.%fZ")| strftime("%h")

报错信息:date "2022-09-21T18:30:04.431Z" does not match format "%Y-%m-%dT%H:%M:%S.%fZ",原因是strptime的%f要求6位微秒,但数据中只有3位毫秒。

解决方案

方案1:修复日期解析格式

通过字符串替换把3位毫秒补全为6位,让strptime可以正常解析:

year 
.createdAt | sub("\\.(\\d{3})Z$"; ".\\1000Z") | strptime("%Y-%m-%dT%H:%M:%S.%fZ") | strftime("%Y")
month 
.createdAt | sub("\\.(\\d{3})Z$"; ".\\1000Z") | strptime("%Y-%m-%dT%H:%M:%S.%fZ") | strftime("%m")
day
.createdAt | sub("\\.(\\d{3})Z$"; ".\\1000Z") | strptime("%Y-%m-%dT%H:%M:%S.%fZ") | strftime("%d")
hour
.createdAt | sub("\\.(\\d{3})Z$"; ".\\1000Z") | strptime("%Y-%m-%dT%H:%M:%S.%fZ") | strftime("%H")

注意:小时的格式化要用%H(24小时制),原配置中的%h是月份缩写,会导致错误。

方案2:直接截取字符串(推荐,无需日期解析)

因为仅关注年、月、日、小时,可直接从createdAt字符串中截取对应部分,完全避免日期解析问题:

year 
.createdAt | .[0:4]
month 
.createdAt | .[5:7]
day
.createdAt | .[8:10]
hour
.createdAt | .[11:13]

这种方式更高效,也不会出现格式匹配问题。

方案3:使用Lambda预处理数据

如果需要更复杂的日期处理,可在Firehose数据流前添加Lambda函数,将createdAt转换为符合%f格式的字符串,或者直接在JSON中新增year、month、day、hour字段,后续Firehose直接使用这些字段作为分区键。

示例Lambda处理逻辑(Python):

import json
import base64

def lambda_handler(event, context):
    output = []
    for record in event['records']:
        payload = json.loads(base64.b64decode(record['data']))
        # 提取日期部分
        dt_str = payload['createdAt']
        payload['year'] = dt_str[:4]
        payload['month'] = dt_str[5:7]
        payload['day'] = dt_str[8:10]
        payload['hour'] = dt_str[11:13]
        # 转换回base64
        output_record = {
            'recordId': record['recordId'],
            'result': 'Ok',
            'data': base64.b64encode(json.dumps(payload).encode('utf-8')).decode('utf-8')
        }
        output.append(output_record)
    return {'records': output}

之后在Firehose中配置分区键为.year、.month、.day、.hour即可。


内容的提问来源于stack exchange,提问作者lamont

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 10:50:22