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

使用Pandas to_sql写入SQLite时1970年前日期报错求助

问题:写入含1970纪元前日期的DataFrame到SQLite触发OSError

在Windows 10系统下,使用Python 3.9/3.11搭配Pandas 2.1.0调用to_sql时,若DataFrame包含1970-01-01(UNIX纪元)之前的日期,会抛出OSError: [Errno 22] Invalid argument,删除对应日期行则执行正常。

原因分析

从报错栈可定位问题根源:Pandas在适配datetime类型到SQLite时,默认使用了基于时间戳的转换逻辑int(val.timestamp())。而Windows系统的Python实现中,datetime.timestamp()方法无法处理纪元前的日期——Windows底层API不支持负时间戳,因此触发无效参数错误。

解决方案

方案1:注册自定义datetime适配器(推荐)

通过注册自定义适配器,强制将datetime对象转换为ISO格式字符串传递给SQLite,SQLite会自动识别并解析为日期类型,完美兼容纪元前后的日期:

import sqlite3
import pandas as pd
from datetime import datetime

# 定义适配器:将datetime转为ISO格式字符串
def adapt_datetime_to_iso(val):
    return val.isoformat()

con = sqlite3.connect("test_db.db")
# 覆盖默认的datetime适配器
sqlite3.register_adapter(datetime, adapt_datetime_to_iso)

df = pd.DataFrame({"a": [1, 2, 3], "b": ["2020-01-01", "2023-05-12", "1967-05-31"]})
df["b"] = pd.to_datetime(df["b"])

# 正常写入包含纪元前日期的DataFrame
df.to_sql("test_table", con, if_exists="append")

方案2:将日期列转为字符串后写入

先把datetime列转换为标准日期字符串,再指定SQLite列类型为TEXT,后续查询时可通过SQLite内置函数转换为日期类型:

import sqlite3
import pandas as pd

con = sqlite3.connect("test_db.db")

df = pd.DataFrame({"a": [1, 2, 3], "b": ["2020-01-01", "2023-05-12", "1967-05-31"]})
# 将datetime转为YYYY-MM-DD格式的字符串
df["b"] = pd.to_datetime(df["b"]).dt.strftime("%Y-%m-%d")

# 指定b列的SQL类型为TEXT
df.to_sql("test_table", con, if_exists="append", dtype={"b": "TEXT"})

# 查询时可通过DATE()函数转换为日期类型
with con.cursor() as cur:
    cur.execute("SELECT a, DATE(b) FROM test_table")
    print(cur.fetchall())

方案3:升级Pandas到修复版本

该问题在Pandas 2.2及以上版本中已被官方修复——默认改用ISO格式适配datetime类型,不再依赖时间戳转换。若环境允许,直接升级Pandas即可解决:

pip install --upgrade pandas

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 14:32:46