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

Pandas to_datetime将NaT转为1970-01-01,如何保留NaT并设为DATE类型?

解决方案:保留NaT并导入为SQL DATE类型

问题出在pandas写入SQL时的类型映射以及数据库表架构的定义,以下是具体解决步骤:

1. 确保DataFrame中正确保留NaT

执行pd.to_datetime(data[column], errors='coerce')后,检查列的 dtype 是否为datetime64[ns]——这是pandas存储日期空值(NaT)的正确类型。如果类型被自动转换(比如变成object),可以手动指定:

data['COLUMN_A'] = pd.to_datetime(data['COLUMN_A'], errors='coerce').astype('datetime64[ns]')

不要用fillna填充NaT,保持原始空值状态。

2. 写入SQL时的关键配置

使用pd.to_sql()时,必须明确指定日期列的SQL类型,并确保数据库表列允许NULL:

核心参数说明

  • dtype:通过SQLAlchemy的Date类型映射,确保pandas将NaT转为SQL的NULL,而非默认日期。
  • 数据库表架构:提前创建表(或让to_sql自动创建)时,确保该列定义为DATE NULL(而非DATE NOT NULL)——如果列被设为非空,数据库会自动将NULL替换为默认值(如1970-01-01)。

示例代码(基于SQLAlchemy)

from sqlalchemy import create_engine, Date
import pandas as pd

# 读取CSV并处理日期列
data = pd.read_csv("your_data.csv")
data["COLUMN_A"] = pd.to_datetime(data["COLUMN_A"], errors="coerce")

# 初始化数据库连接(替换为你的数据库串)
engine = create_engine("postgresql://user:pass@host:port/dbname")
# MySQL示例:engine = create_engine("mysql+pymysql://user:pass@host:port/dbname")

# 写入SQL表
data.to_sql(
    name="target_table",
    con=engine,
    if_exists="replace",  # 根据需求选append/replace
    index=False,
    dtype={
        "COLUMN_A": Date()  # 明确映射为SQL DATE类型
    }
)

3. 常见问题排查

  • 如果使用SQLite:SQLite原生没有DATE类型,会以TEXT存储,NaT会被存为'NaT'字符串。若需要严格DATE类型,建议改用支持原生DATE的数据库(如PostgreSQL/MySQL)。
  • 若仍出现1970-01-01:检查目标表的列定义——如果是DATE NOT NULL,修改为DATE NULL即可解决,这是数据库强制非空导致的默认值填充。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 05:15:11