如何解决DBT+Snowflake中整数格式日期取最小值报错问题
解决DBT+Snowflake中
dbt_date.get_date_dimension的整数转换错误 问题场景
使用DBT结合Snowflake构建日期维度表(DIM_DATE),源表raw_events_pivot中的Event_Date列以整数格式存储日期(例如:20230101)。硬编码起始日期时模型运行正常,但将起始日期设为Event_Date的最小值时,出现以下错误:
17:18:04 252005: Failed to convert current row, cause: Python int too large to convert to C int
原模型代码:
{{ config( alias='DIM_DATE', materialized = "table" ) }} {% set get_min_date_query %} select min(event_date::varchar) from {{ ref('raw_events_pivot') }} {% endset %} {% set min_query_result = run_query(get_min_date_query) %} {% if execute %} {% set min_year_result = min_query_result.columns[0].values()[0] %} {% else %} set min_year_result = 0 {% endif %} {% set start_date = get_start_date(min_year_result ) %} with date_create as ( {{ dbt_date.get_date_dimension( start_date , '2023-12-31' )}} ) SELECT DATE_DAY AS date, YEAR_NUMBER as year, DAY_OF_WEEK_NAME_SHORT as day_name, WEEK_OF_YEAR, 'WK' || WEEK_OF_YEAR || '-' || YEAR_NUMBER as week_year, --WK52-2022 MONTH_OF_YEAR as month_nr, MONTH_NAME, MONTH_NAME_SHORT, QUARTER_OF_YEAR as quarter, 'Q'|| QUARTER_OF_YEAR || '-' || YEAR_NUMBER AS quarter_year, --Q1-2023 current_user() as INT_LoadBy, sysdate() as INT_UPDATETIMESTAMPUTC, 'DBT' as COD_IntSourceSystem FROM Date
错误原因
- 参数类型不匹配:
get_start_date函数预期接收4位年份整数(如2023),但实际传递的是8位日期整数/字符串(如20230101),导致函数内部转换时超出C int取值范围。 - 日期格式错误:传递给
dbt_date.get_date_dimension的起始日期不是标准ISO格式(YYYY-MM-DD),而是数字字符串/整数,引发内部转换逻辑出错。 - CTE引用笔误:最终查询的
FROM Date应为FROM date_create,属于语法错误。
修复方案
方案1:直接生成标准ISO格式起始日期
修改最小日期查询逻辑,将整数日期转换为标准ISO日期字符串,无需依赖get_start_date函数:
{{ config( alias='DIM_DATE', materialized = "table" ) }} {% set get_min_date_query %} -- 将整数日期转为Snowflake日期类型,再格式化为ISO字符串 select TO_CHAR(MIN(TO_DATE(event_date::VARCHAR, 'YYYYMMDD')), 'YYYY-MM-DD') from {{ ref('raw_events_pivot') }} {% endset %} {% set min_query_result = run_query(get_min_date_query) %} {% if execute %} -- 直接获取标准日期字符串 {% set start_date = min_query_result.columns[0].values()[0] %} {% else %} -- 离线编译时用默认测试日期 {% set start_date = '2023-01-01' %} {% endif %} with date_create as ( {{ dbt_date.get_date_dimension(start_date, '2023-12-31') }} ) SELECT DATE_DAY AS date, YEAR_NUMBER as year, DAY_OF_WEEK_NAME_SHORT as day_name, WEEK_OF_YEAR, 'WK' || WEEK_OF_YEAR || '-' || YEAR_NUMBER as week_year, MONTH_OF_YEAR as month_nr, MONTH_NAME, MONTH_NAME_SHORT, QUARTER_OF_YEAR as quarter, 'Q'|| QUARTER_OF_YEAR || '-' || YEAR_NUMBER AS quarter_year, current_user() as INT_LoadBy, sysdate() as INT_UPDATETIMESTAMPUTC, 'DBT' as COD_IntSourceSystem FROM date_create -- 修复CTE引用错误
方案2:如果必须使用get_start_date函数
若get_start_date是自定义函数且需传递4位年份参数,修改参数提取逻辑:
{% if execute %} {% set min_date_str = min_query_result.columns[0].values()[0] %} -- 提取前4位作为年份参数 {% set start_year = min_date_str[:4] %} {% set start_date = get_start_date(start_year) %} {% else %} {% set start_date = '2023-01-01' %} {% endif %}
关键说明
dbt_date.get_date_dimension的参数必须是ISO格式的日期字符串(如'2023-01-01'),而非整数或数字字符串。- 避免直接对整数转varchar后的日期取min,应先转为Snowflake日期类型再取最小值,确保排序逻辑正确(字符串排序可能在极端场景下出错)。
内容的提问来源于stack exchange,提问作者Catarina Ribeiro
相关产品推荐
相关产品推荐

