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

Databricks读取Parquet强制Schema失败问题求助

问题:Parquet读取时强制Schema转换失败(Long转Int)

场景说明

Parquet源文件中Year列类型为long,目标表中该列定义为int。尝试通过指定目标表Schema来强制转换类型,代码如下:

df = (
    spark
    .read
    .schema(spark.table(f'{CATALOG_NAME}.{BRONZE_SCHEMA}.{SLA_TARGET}').schema)
    .parquet(RAW_EXTERNAL_LOCATION_PATH + f"/{SLA_TARGET}/{SLA_TARGET}.parquet")
)

报错信息

SchemaColumnConvertNotSupportedException: column: [Year], physicalType: INT64, logicalType: int

疑问

  1. 不想先读取再转换,为何无法通过指定Schema强制转换?
  2. 当前环境为Databricks 14.3LTS、Spark 3.5.0,按照Databricks文档,vectorizedReader设为false仅针对decimal类型,即使设置该参数,仍出现FileReadException读取失败。

解答

原因分析

Spark读取Parquet时,指定Schema的强制类型转换仅支持安全无数据丢失的兼容转换。Long(INT64)转Int(INT32)属于可能丢失精度的转换(比如Long值超过Int最大值2147483647时会溢出),因此Parquet Reader默认禁止这种直接强制转换,避免潜在数据损坏。

解决方案

若确认源数据中Year列所有值都在Int取值范围(-2147483648 至 2147483647)内,可通过以下两种方式实现类型转换,无需先读取全量数据再处理:

方法1:自定义Schema并强制转换

手动复制目标表Schema,将Year列改为IntegerType,结合mergeSchema=false确保严格使用自定义规则:

from pyspark.sql.types import StructType, StructField, IntegerType

# 复制目标表Schema并修改Year列类型
target_schema = spark.table(f'{CATALOG_NAME}.{BRONZE_SCHEMA}.{SLA_TARGET}').schema
custom_schema = StructType([
    StructField("Year", IntegerType(), nullable=field.nullable) if field.name == "Year" else field
    for field in target_schema.fields
])

df = (
    spark
    .read
    .option("mergeSchema", "false")
    .schema(custom_schema)
    .parquet(RAW_EXTERNAL_LOCATION_PATH + f"/{SLA_TARGET}/{SLA_TARGET}.parquet")
)

方法2:用Spark SQL直接转换写入目标表

通过DDL语句直接读取Parquet并转换类型,底层会优化执行流程,避免全量加载后转换:

CREATE TABLE {CATALOG_NAME}.{BRONZE_SCHEMA}.{SLA_TARGET}
AS SELECT
    CAST(Year AS INT) AS Year,
    -- 其他列直接选择
    col1, col2, ...
FROM parquet.`{RAW_EXTERNAL_LOCATION_PATH}/{SLA_TARGET}/{SLA_TARGET}.parquet`

关于vectorizedReader的说明

vectorizedReader关闭仅解决Decimal类型的兼容问题,对Long转Int这类数值范围不兼容的场景无效,因此设置后依然报错是正常现象。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 17:15:00