New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fetching NULL in DATE column gives ValueError: year 0 is out of range #475
Comments
|
unixODBC log attached. ODBC log from windows (where the issue does not appear with pyodbc 4.0.24 installed from pypi) |
|
I can workaround with an output converter function: def null_date_converter(value):
val_str = value.decode('utf-8') # ? is it really utf-8
#print(f'{__name__} value: {val_str}')
if value is None:
return None
else:
return datetime.datetime.strptime(val_str, "%Y-%m-%d").date()
con.add_output_converter(pyodbc.SQL_TYPE_DATE, null_date_converter)Although the workaround behaves OK on both platforms it is not an ideal solution. |
|
Adding a TRACE if (sizeof(cbFetched) == sizeof(long))
TRACE("GetDataTimestamp: cbFetched %ld != %d SQL_NULL_DATA\n", cbFetched, SQL_NULL_DATA);
else
TRACE("GetDataTimestamp: cbFetched %d != %d SQL_NULL_DATA\n", cbFetched, SQL_NULL_DATA);gives GetDataTimestamp: cbFetched=4294967295 SQL_NULL_DATA=-1 4294967295 is 2^32 -1 so it's looking like an unsigned long is coming in somewhere. Maybe a problem in unixODBC (or my compilation of it) rather than pyodbc? |
|
Compiler warnings that I failed to notice last night: Though I don't think these are relevent to this problem |
|
The NULL detection for output converters seems to work, GetDataUser calls ReadVarColumn which uses this: if (ret == SQL_SUCCESS && (int)cbData < 0)
{
// HACK: FreeTDS 0.91 on OS/X returns -4 for NULL data instead of SQL_NULL_DATA
// (-1). I've traced into the code and it appears to be the result of assigning -1
// to a SQLLEN. We are going to treat all negative values as NULL.
ret = SQL_NULL_DATA;
cbData = 0;
}rather than a direct comparison of cbData to SQL_NULL_DATA - note also the explicit cast (int)cbData. I'm tempted to suggest replacement of the current NULL test in GetDataTimestamp (and presumably any other places where we check for NULL from SQLGetData) with that used in ReadVarColumn, i.e. if (cbFetched == SQL_NULL_DATA)with if ((int)cbFetched < 0) // HACK: FreeTDS 0.91 on OS/X returns -4 for NULL data instead of SQL_NULL_DATA (-1)Does this sound reasonable? If so I'm happy to try putting together a pull-request. |
|
I believe this could be a bug in your ODBC driver. Just to be sure, you can run |
|
Hi, thanks for the comment. |
|
That further narrows it down to the ODBC driver, the unixODBC configuration appears correct. |
|
I think I've found the problem, as you suggested in the ODBC driver. Thanks for your input @v-chojas ! |
|
What is the workaround for this error? |
|
same question |
|
@paul-lilley @v-chojas |
Environment - where the ValueError is given
Issue
When fetching NULL from a nullable DATE column (or a DATE variable set to NULL) pyodbc raises
ValueError: year 0 is out of range
I'd expect it to return None (which it in fact does when run in Anaconda on Windows against the same DB2). I've not tested against other databases.
Code to recreate the issue:
The text was updated successfully, but these errors were encountered: