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

使用Trino向PostgreSQL插入含Null值数据时遇io.trino.spi.type.IntegerType错误

问题:Trino读取Parquet插入PostgreSQL时Null值触发类型错误

报错与排查

执行插入操作时触发如下错误:

Query 20250413_125415_00070_tsd8v failed: io.trino.spi.type.IntegerType

经排查,问题出在user_id列的Null值,但PostgreSQL本身支持Null;即使将Trino中该列类型改为VARCHAR,仍会出现同类VARCHAR相关错误。

相关代码与数据

Trino外部表Schema

./trino --execute "
CREATE SCHEMA IF NOT EXISTS minio.data
WITH (location = 's3a://data/');

CREATE TABLE minio.data.main (
    project_name VARCHAR,
    id_list ARRAY(INTEGER),
    user_id INTEGER
)
WITH (
    format = 'parquet',
    external_location = 's3a://data/'
);"

PostgreSQL插入语句

./trino --execute "
INSERT INTO postgres.public.data
SELECT 
    project_name,
    ARRAY_JOIN(id_list, ',') AS id_list,
    user_id      --this column caused problem
FROM minio.data.main;"

原始JSON样本

[
  {
    "project_name": "Ring",
    "id_list": [
      1111,
      2222,
      3333
    ],
    "user_id": 9999
  },
  {
    "project_name": "Square",
    "id_list": [
      11,
      12
    ],
    "user_id": null
  }
]

原因分析

  1. Trino表Schema与Parquet实际存储不匹配:JSON转Parquet时,包含Null的列会被标记为可空类型,但Trino创建外部表时显式声明user_id INTEGER(默认非可空),导致Trino读取Parquet时类型校验失败。
  2. 类型转换的底层兼容性问题:即使修改为VARCHAR,若Parquet中该列的Null存储格式不符合Trino对VARCHAR类型的预期,同样会触发类型错误。

解决方法

1. 修正Trino表Schema,显式声明列可空

将user_id INTEGER改为user_id INTEGER NULL,重新创建外部表:

./trino --execute "
CREATE SCHEMA IF NOT EXISTS minio.data
WITH (location = 's3a://data/');

DROP TABLE IF EXISTS minio.data.main;  -- 先删除原表
CREATE TABLE minio.data.main (
    project_name VARCHAR,
    id_list ARRAY(INTEGER),
    user_id INTEGER NULL  -- 显式标记该列允许Null
)
WITH (
    format = 'parquet',
    external_location = 's3a://data/'
);
"

2. 验证Parquet文件的列类型

使用parquet-tools工具查看Parquet文件的实际schema,确认列的可空属性:

parquet-tools schema s3a://data/*.parquet

输出中若user_id列带有(nullable=true),则说明存储格式正确,只需调整Trino表Schema即可。

3. 修复JSON转Parquet的转换逻辑

确保转换工具(如Spark、Pandas)生成Parquet时正确处理可空列:

  • 用Spark转换时,设置spark.sql.parquet.writeLegacyFormat=false,避免旧格式导致的类型不兼容;
  • 用Pandas转换时,确保user_id列的dtype为Int64(可空整数类型)而非int64(非可空)。

4. 插入时显式处理Null(可选)

如果仍有兼容性问题,可在SELECT语句中显式处理Null值,比如替换为业务允许的默认值:

./trino --execute "
INSERT INTO postgres.public.data
SELECT 
    project_name,
    ARRAY_JOIN(id_list, ',') AS id_list,
    COALESCE(user_id, 0) AS user_id  -- 用0替代Null,可根据业务需求调整
FROM minio.data.main;"

内容的提问来源于stack exchange,提问作者Prof.Plague

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 10:54:52