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

将Polars数据写入SQL Server时遇类型转换错误求助

问题:Polars写入SQL Server时datetime字段抛出DataError

我有个Python脚本,从CSV读取数据后写入SQL Server临时表,使用Polars添加了process_time字段:

data = data.with_columns(
    (
        pl.datetime(
            year=current_date.year,
            month=current_date.month,
            day=current_date.day,
            hour=current_date.hour,
            minute=current_date.minute,
            second=current_date.second,
        )
    ).alias("process_time"),
)

SQL表对应的字段定义:

...
[process_time] [datetime] NULL,
...

执行polars.to_sql()时抛出报错:

DataError: (pyodbc.DataError) ('22018', '[22018] [Microsoft][ODBC Driver 17 for SQL Server]Invalid character value for cast specification (0) (SQLExecute)')

手动导入处理后的文件时,SQL Server提示process_time字段可能存在数据丢失。

困惑点:这段逻辑上月运行正常,本月无代码变更却报错。已确认无空行、NULL值,process_time每行值完全一致,用Polars的unique()方法确认类型是datetime[μs],值为2023-11-08 14:21:33。

补充信息:转成Pandas后查看唯一值:

<ArrowExtensionArray>
[Timestamp('2023-11-08 15:57:45')]
Length: 1, dtype: timestamp[us][pyarrow]

Polars版本信息:

--------Version info---------
Polars:              0.19.12
Index type:          UInt32
Platform:            Windows-10-10.0.19045-SP0
Python:              3.10.11 (tags/v3.10.11:7d4cc5a, Apr  5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)]

----Optional dependencies----
adbc_driver_sqlite:  <not installed>
cloudpickle:         <not installed>
connectorx:          <not installed>
deltalake:           <not installed>
fsspec:              <not installed>
gevent:              <not installed>
matplotlib:          <not installed>
numpy:               1.26.1
openpyxl:            <not installed>
pandas:              2.1.2
pyarrow:             13.0.0
pydantic:            <not installed>
pyiceberg:           <not installed>
pyxlsb:              <not installed>
sqlalchemy:          2.0.22
xlsx2csv:            <not installed>
xlsxwriter:          <not installed>

排查思路与解决方案

1. 时间精度不匹配导致类型转换失败

SQL Server的datetime类型仅支持毫秒级精度(3位小数),而你的Polars时间字段是微秒级(6位小数)。即使显示的时间值没有小数位,底层存储的微秒精度在与ODBC驱动交互时,可能被解析为带冗余小数的格式,导致SQL Server无法完成转换。

解决方法:将Polars的datetime字段强制转换为毫秒精度:

data = data.with_columns(
    pl.col("process_time").cast(pl.Datetime(time_unit="ms"))
)

2. 修复Polars to_sql的类型映射问题

Polars的to_sql依赖SQLAlchemy或pyodbc做类型映射,特定版本组合下可能存在微秒datetime到SQL Server datetime的映射bug。可以尝试两种方式:

  • 显式指定SQL类型:在to_sql中通过dtype参数明确字段类型
from sqlalchemy import DateTime

data.to_sql(
    "your_temp_table",
    your_db_connection,
    dtype={"process_time": DateTime()},
    # 其他参数(如if_exists、index等)保持原有配置
)
  • 转Pandas后写入:绕开Polars的类型映射逻辑,直接用Pandas的to_sql
data.to_pandas().to_sql(
    "your_temp_table",
    your_db_connection,
    dtype={"process_time": DateTime()},
    # 其他参数保持原有配置
)

3. 排查依赖版本变更

即使代码未修改,依赖包可能自动更新导致兼容性问题:

  • 检查ODBC Driver 17 for SQL Server是否有更新,尝试回滚到上月可用版本
  • 核对pyarrow、SQLAlchemy版本是否与上月一致,当前你使用pyarrow 13.0.0、SQLAlchemy 2.0.22,若之前版本不同,可尝试降级测试

4. 清理临时表元数据缓存

SQL Server的临时表可能存在元数据缓存,尝试先删除临时表再重新创建,或更换临时表名称测试,避免旧元数据干扰。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 15:47:26