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

导入数据时触发ValueError: year -1 is out of range错误的技术求助

解决psycopg2+pandas提取PostgreSQL数据时的年份越界错误

问题场景

使用psycopg2和pandas从PostgreSQL数据库提取数据时,触发ValueError: year -1 is out of range错误。已知待处理的时间戳数据存在负年份、空值这类无效值,现有代码的错误处理逻辑未能解决问题。

问题原因

现有代码先执行了SELECT MIN(dt_date)获取最小日期,但如果这个最小值本身是负年份这类Python datetime无法解析的无效值,psycopg2在拉取数据时会直接尝试将PostgreSQL的日期对象转换为Python datetime,这一步就会触发报错,根本走不到后续pandas的to_datetime(errors='coerce')处理环节。

解决方案

1. SQL层面提前过滤无效数据

直接在查询语句中筛选出Python datetime支持范围内的日期(Python datetime支持1~9999年),同时排除空值,从源头避免无效数据进入Python:

SELECT *
FROM prod_external.tran_y_register
WHERE entry_type = 1 
  AND dt_date IS NOT NULL
  AND dt_date >= '0001-01-01' 
  AND dt_date <= '9999-12-31'
ORDER BY dt_date;

2. 修正最小日期查询逻辑

如果需要基于最小有效日期拉取数据,先查询有效日期的最小值,而非所有数据的最小值:

SELECT MIN(dt_date)
FROM prod_external.tran_y_register
WHERE entry_type = 1
  AND dt_date IS NOT NULL
  AND dt_date >= '0001-01-01' 
  AND dt_date <= '9999-12-31';

3. SQL层将无效值转为NULL保留

如果不想过滤掉无效数据,而是要保留对应行并在后续处理,可以用CASE语句将无效日期转为NULL:

SELECT 
  *,
  CASE 
    WHEN dt_date IS NULL OR dt_date < '0001-01-01' OR dt_date > '9999-12-31' THEN NULL 
    ELSE dt_date 
  END AS dt_date_clean
FROM prod_external.tran_y_register
WHERE entry_type = 1
ORDER BY dt_date;

后续在pandas中处理dt_date_clean列即可。

修改后的完整代码

import psycopg2
import pandas as pd

# 假设conn已完成数据库连接初始化
cur = conn.cursor()

try:
    # 直接拉取有效范围内的日期数据
    cur.execute("""
        SELECT *
        FROM prod_external.tran_y_register
        WHERE entry_type = 1 
          AND dt_date IS NOT NULL
          AND dt_date >= '0001-01-01' 
          AND dt_date <= '9999-12-31'
        ORDER BY dt_date;
    """)
    
    rows = cur.fetchall()
    column_names = [desc[0] for desc in cur.description]
    df = pd.DataFrame(rows, columns=column_names)
    
    # 额外添加一层本地处理保险,防止SQL过滤有遗漏
    df['dt_date'] = pd.to_datetime(df['dt_date'], errors='coerce')
    df.dropna(subset=['dt_date'], inplace=True)
    
    print(df)

except psycopg2.Error as e:
    print("Error: Could not fetch data from the table")
    print(e)
except ValueError as e:
    # 捕获可能遗漏的日期转换错误
    print("Error: Invalid date value encountered")
    print(e)

# 关闭资源
cur.close()
conn.close()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:54:50