import pandas as pd
from io import StringIO
import boto3
import json
import datetime
import oracledb
import os
def DateTimeConverter(value):
if value.year > 9999:
return datetime.datetime.now()
else:
return value
def OutputHandler(cursor, name, defaulttype, length, precision, scale):
print("OutputHandler: ", name, defaulttype, length, precision, scale)
if defaulttype == oracledb.DB_TYPE_DATE:
return cursor.var(oracledb.DB_TYPE_DATE, arraysize=cursor.arraysize, outconverter=DateTimeConverter)
def connect_to_db(user, password, host, port, service):
try:
conn = oracledb.connect(user=user, password=password,
dsn=host+":"+port+"/"+service, mode=oracledb.SYSDBA)
conn.outputtypehandler = OutputHandler
return conn
except oracledb.DatabaseError as e:
print('Error connecting to database: {}\n'.format(e))
raise e
connection = connect_to_db("", "", "", "5500", "")
cursor = connection.cursor()
cursor.execute("select T$RGDT from T_ERPLNFP3.TBPTMM111100")
data = cursor.fetchall()
print("Row count: ", cursor.rowcount)
print(data[0])
cursor.close()
connection.close()
我尝试使用Python和oracledb模块从Oracle数据库中获取数据。表中的一列具有日期时间格式,列中的所有值均为'4712-01-01 00:00:00.000'。然而,当我运行代码时,我得到以下错误:
`File "src/oracledb/impl/thin/buffer.pyx", line 587, in oracledb.thin_impl.Buffer.read_date
File "src/oracledb/impl/thin/buffer.pyx", line 359, in oracledb.thin_impl.Buffer.parse_date
File ".eggs/Cython-0.29.33-py3.11-linux-x86_64.egg/Cython/Includes/cpython/datetime.pxd", line 120, in cpython.datetime.datetime_new
ValueError: year 60824 is out of range`
我不能更改源数据,所以我需要找到一种方法来获取数据,而不对数据库进行任何更改。当我在DB_Veawer或类似软件中运行相同的查询时,我得到的输出没有任何问题。
有人能帮助我理解为什么会发生这个错误,以及我如何使用Python和OracleDB模块获取数据而没有任何问题吗?任何帮助都将不胜感激。谢谢。
1条答案
按热度按时间b4wnujal1#
表中的一列具有日期时间格式
这是什么意思?它是哪种数据类型?我假设它不是
DATE
也不是TIMESTAMP
而是VARCHAR2
,并且值以字符串的形式存储在-你称之为-“日期时间格式”并且所有列中的值为'4712-01-01 00:00:00.000'。
显然不是全部根据
ValueError:年份60824超出范围`
这个值- 60824 -听起来像我之前说过的,你把值存储为字符串,因为Oracle支持从-4713到+9999的年份(没有年份0)。例如:
你说过
当我在DB_Veawer或类似软件中运行相同的查询时,我得到的输出没有任何问题。
好吧,你确定你运行的查询返回了所有行吗?GUI工具通常返回前50或几百行,这意味着-如果存储了无效值 * 超出了初始范围 *,查询不会失败。
如果column包含无效值,你必须先找到它们,然后决定你想对它们做什么。如果是SQL,我可能会在
CASE
表达式中使用SUBSTR
函数。例如:也许你可以在Python中实现类似的东西;看不出来。
当然,它只是取决于你在该列中找到了什么新的 * 垃圾 *。因为它存储字符串,所以没有什么可以阻止像'12 cF-0x-3$'这样的值,它遵循“yyyy-mm-dd”格式,但这不是一个有效的日期值。
在我看来,这似乎是人们在将日期值存储到不适当的数据类型列中时遇到的另一个问题。