Ich denke nicht, dass das an dem tatsächlichen Inhalt des Feldes liegt. FKEADT ist das erste Feld in der Tabelle, das laut cursor.description die Klasse datetime.date hat. Und dahin sollte der enthaltene Wert eigentlich konvertiert werden. datetime.date kennt aber keine Stunden, weshalb es eigentlich gar nicht zu dem Fehler kommen kann.
Du könntest das Problem umgehen, indem du die entsprechenden Felder nicht mit selektierst (wie hier bereits im Thread vorgeschlagen kein * im SELECT-Statement). Das funktioniert aber nur so lange, bis du eines der Felder tatsächlich brauchst.
Warum das auf dem einen Rechner geht und auf dem anderen nicht, verstehe ich allerdings nicht. Ich hätte nämlich auf ein Problem im ODBC-Treiber getippt. Bzw. die Einstellungen, die er ggf. verwendet und aus dem System liest.
pyodbc ValueError: hour must be in 0..23
Das Problem lässt mich leider immer noch nicht los.
Folgendes habe ich noch probiert.
Der Datensatz mit dem Datum, welches den Fehler erzeugt, steht in der AS400 wie folgt:
19.12.2019
Auf dem Rechner wo die Abfrage läuft sieht die Ausgabe wie folgt aus:
2019-12-19
Die anderen Rechner liefern den ValueError: Hours must be in 0..23
Hat jemand eine Idee dazu???
Folgendes habe ich noch probiert.
Der Datensatz mit dem Datum, welches den Fehler erzeugt, steht in der AS400 wie folgt:
19.12.2019
Auf dem Rechner wo die Abfrage läuft sieht die Ausgabe wie folgt aus:
2019-12-19
Die anderen Rechner liefern den ValueError: Hours must be in 0..23
Hat jemand eine Idee dazu???
Da habe ich noch nie mit gearbeitet.
Aber offensichtlich liegt das Problem ja irgendwo in der ODBC-Schnittstelle. pyodbc erkennt korrekt, dass es sich um eine Datums-Spalte handelt und möchte die nach datetime.date konvertieren. Das schlägt allerdings fehl.
Ich würde versuchen an die Rohdaten zu kommen, die tatsächlich kommen um hier vielleicht einen Unterschied zwischen den Rechnern zu sehen, auf denen es funktioniert und denen, auf denen es nicht funktioniert.
Hier wird beschrieben, wie man eine eigene Konverterfunktion in pyodbc hinterlegt. Und hier stehen die verschiedenn Datentypen, die pyodbc verwendet.
Vielleicht funktioneirt so etwas (ungetestet, musst du vielleicht ein bischen basteln):
Wenn das so läuft, wie ich mir das vostelle, wird die Konverfunktion für datetime.date ersetzt und mit etwas Glück das ausgegeben, was vor der Konvertierung kommt.
Aber offensichtlich liegt das Problem ja irgendwo in der ODBC-Schnittstelle. pyodbc erkennt korrekt, dass es sich um eine Datums-Spalte handelt und möchte die nach datetime.date konvertieren. Das schlägt allerdings fehl.
Ich würde versuchen an die Rohdaten zu kommen, die tatsächlich kommen um hier vielleicht einen Unterschied zwischen den Rechnern zu sehen, auf denen es funktioniert und denen, auf denen es nicht funktioniert.
Hier wird beschrieben, wie man eine eigene Konverterfunktion in pyodbc hinterlegt. Und hier stehen die verschiedenn Datentypen, die pyodbc verwendet.
Vielleicht funktioneirt so etwas (ungetestet, musst du vielleicht ein bischen basteln):
Code: Alles auswählen
import pyodbc
import struct
def handle_date(dto_value):
print(f"Raw data: {dto_value}")
tup = struct.unpack("<6hI2h", dto_value)
print(f"After unpack: {tup}")
with pyodbc.connect(
driver='{iSeries Access ODBC Driver}',
system='172.16.0.3',
uid='user',
pwd='password')as connection:
connection.add_output_converter(pyodbc.SQL_TYPE_DATE, handle_date)
cursor = connection.cursor()
sql_statement = """SELECT FKEADT FROM WAWBRUDTA.FERKPU
WHERE FKAUNR >= '1900000' ORDER BY FKAUNR
LIMIT 1"""
cursor.execute(sql_statement)
cursor.fetchone()