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

为何DuckDB导入Polars的Enum列会转换为VARCHAR列?

为什么DuckDB不会将Polars的Enum类型转换为自身的Enum类型?

问题重现

用户使用Polars创建包含Enum列的DataFrame:

import polars as pl

values = ["a", "b", "c"]
df = pl.DataFrame(pl.Series("x", values, dtype=pl.Enum(values)))
print(df)

执行结果:

shape: (3, 1)
┌──────┐
│ x    │
│ ---  │
│ enum │
╞══════╡
│ a    │
│ b    │
│ c    │
└──────┘

随后用DuckDB查询该DataFrame:

import duckdb as ddb

ddb.sql("SELECT * FROM df").show()

查询结果显示原Enum列被转换为VARCHAR类型:

┌─────────┐
│    x    │
│ varchar │
├─────────┤
│ a       │
│ b       │
│ c       │
└─────────┘

用户最初怀疑是Parquet文件读取导致的问题,但直接查询Polars DataFrame也出现同样情况,因此提出疑问:为什么DuckDB不将Polars的Enum转换为DuckDB的Enum类型?

原因解释

核心原因是Polars与DuckDB的Enum类型在底层实现、类型映射逻辑上存在差异,且当前DuckDB的Python集成未针对Polars Enum做专门的转换适配:

  • Polars的Enum基于字符串集合定义,内部可能用整数编码存储,但对外以字符串形式暴露;
  • DuckDB的Enum类型需要显式定义枚举值集合,而DuckDB读取Polars DataFrame时,默认仅识别通用基础类型(如字符串、数值),不会主动解析Polars Enum的元数据来创建对应的DuckDB Enum类型;
  • 无论直接读取Polars DataFrame还是读取Parquet文件,本质都是DuckDB没有内置Polars Enum到自身Enum的转换逻辑,因此会降级处理为VARCHAR类型。

如果需要在DuckDB中保留Enum类型,可以手动显式转换:先在DuckDB中定义对应Enum类型,再将Polars的Enum列转换为该类型,示例代码如下:

import duckdb as ddb
import polars as pl

values = ["a", "b", "c"]
df = pl.DataFrame(pl.Series("x", values, dtype=pl.Enum(values)))

# 在DuckDB中定义枚举类型
ddb.sql(f"CREATE TYPE my_enum AS ENUM({', '.join([f'{repr(v)}' for v in values])})")
# 转换列类型并查询
ddb.sql("SELECT CAST(x AS my_enum) FROM df").show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 23:45:05