Fix for parsing timestamp field in Oracle

Bug #1273921 reported by Sandip Bhattacharya
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
JayDeBeApi
Confirmed
Medium
Unassigned

Bug Description

As per comments in the code, timestamp field in Oracle doesn't get converted to string easily. I just wanted to point out that the following modification in dbapi2.py worked for me.

==============================================================
--- dbapi2.py 2013-10-15 20:07:50.000000000 +0000
+++ dbapi2_.py 2014-01-29 02:15:03.480118533 +0000
@@ -435,6 +435,7 @@
         pass

 def _to_datetime(java_val):
+ java_val = java_val.toJdbc()
     d = datetime.datetime.strptime(str(java_val)[:19], "%Y-%m-%d %H:%M:%S")
     if not isinstance(java_val, basestring):
         d = d.replace(microsecond=int(str(java_val.getNanos())[:6]))
==========================================================

I am not sure if this will break other jdbc libraries though.

Revision history for this message
Bastian (baztian) wrote :

Thanks for the patch. It's indeed Oracle specific and would break other jdbc libraries. That's why I'm not going to include your patch. I've already planned but not fully implemented another optional parameter for the connect method that would allow you to specify a mapping that's specific to your database. Something similar to this:

def your_ora_todatetime(java_val):
    java_val = java_val.toJdbc()
    d = datetime.datetime.strptime(str(java_val)[:19], "%Y-%m-%d %H:%M:%S")
    if not isinstance(java_val, basestring):
        d = d.replace(microsecond=int(str(java_val.getNanos())[:6]))
    return str(d)

conn = connect('oracle.jdbc.OracleDriver', ['jdbc:oracle:thin:@//foo:1521/bar'], converters=dict(TIMESTAMP=your_ora_todatetime))

I'll try to implement this in the next couple of weeks if I find the time. Most of the code is already there. I think I'll include your sample implementation in the documentation.

Thank you!

Changed in jaydebeapi:
importance: Undecided → Medium
status: New → Confirmed
Revision history for this message
Sandip Bhattacharya (sandipb) wrote :

Since all we are doing here is converting Oracle specific data to a standardized jdbc data, we would normally just need:

def your_ora_todatetime(java_val):
    java_val = java_val.toJdbc()
    return _todatetime(java_val)

Would it make sense to instead give users an option to "filter" driver specific data to jdbc standard?

e.g.
conn = connect('oracle.jdbc.OracleDriver', ['jdbc:oracle:thin:@//foo:1521/bar'],
                              jdbc_converters=dict(TIMESTAMP=lambda x: x.toJdbc()))

If fact, since we know this driver specific issue, we may have this map in the dbapi2 module itself:
     jdbc_converters = {
                                         'oracle.jdbc.OracleDriver': {
                                                               'TIMESTAMP': lambda x: x.toJdbc()
                                                            }
                                       }

Your converter logic can then check if there is an additional jdbc converter required for a specific driver before doing the usual processing.

Revision history for this message
Bastian (baztian) wrote :

Thanks for the idea. I'll keep that in mind. My first thought is that I don't want to start keeping db-specific stuff in my code because I don't want to modify it for every db. Imagine that there might be cases where you use the same driver class name but have different driver versions or databases that act differently for the types. So it would soon get too complicated.

On the other hand it would be nice to have a tool that is able to deal with every databse without much tinkering.

Feel free to play branch JayDeBeApi. If you found a cool solution I would love to merge you stuff :) Anyway, I'll try to address this issue in some way when I find time.

Revision history for this message
Bastian (baztian) wrote :
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.