2013-03-14 13 views
6

Ich verwende MySQLdb, um mit der MySQL-Datenbank zu kommunizieren, und kann alle Ergebnismengen dynamisch abrufen.mysqldb konvertiert Zeitstempeldaten in None

Mein Problem ist, dass, sobald ich die Ergebnismenge erhalten habe, gibt es ein paar Spalten, die als Zeitstempel in mysql deklariert werden, aber wenn es abgerufen wird, wird es zu keiner.

Ich habe zwei Spalten, beide sind Zeitstempel deklariert, aber eine gibt korrekte Daten zurück, während andere keine zurückgibt. Sowohl Utime als auch Enddatum sind Zeitstempel, aber Utime wird nicht korrekt zurückgegeben, während Enddatum tut.

['utime', 'userstr', 'vstr_client', 'enddate'] 

((None, '000102030ff43260gg0809000000000004', '7.7.0', '1970-01-01 12:00:00.000000')) 

def parse_data_and_description(cursor, data): 

    res = [] 
    cols = [d[0] for d in cursor.description] 
    print cols 
    print data 

    for i in data: 
     res.append(OrderedDict(zip(cols, i))) 
    return res 

def call_multi_rs(sp, args): 

    rs_id=0; 
    conn = connect() 
    cursor = conn.cursor() 
    try: 
     conn.autocommit(True) 
     cursor.execute ("CALL %s%s" % (sp, args)) 
     while True: 
      rs_id+=1 
      data = cursor.fetchone() 
      listout = parse_data_and_description(cursor, data) 
      print listout 
      if cursor.nextset()==None: 
      # This means no more recordsets available 
      break 

Antwort

7

schließlich nach niemandem beantwortet oder hat versucht, mehr Informationen zu finden, ging ich weiter und sah mehr Lösungen und fand, dass die MySQLdb Bibliothek, die die Datentypen von SQL in Python konvertiert und es ist ein Fehler, der nicht den Zeitstempel konvertiert.

Ich weiß immer noch nicht, warum einer von ihnen konvertiert wird und der andere nicht. Wenn jemand das herausfinden kann, bitte aktualisieren Sie dies.

Aber hier ist die Änderung, die bei der Verbindung mit der MySQL-Datenbank vorgenommen werden muss. MySQLdb kann nicht ein Python-Datetime-Objekt

try: 
    import MySQLdb.converters 
except ImportError: 
    _connarg('conv') 

def connect(host='abc.dev.local', user='abc', passwd='def', db='myabc', port=3306): 

    try: 
     orig_conv = MySQLdb.converters.conversions 
     conv_iter = iter(orig_conv) 
     convert = dict(zip(conv_iter, [str,] * len(orig_conv.keys()))) 
     print "Connecting host=%s user=%s db=%s port=%d" % (host, user, db, port) 
     conn = MySQLdb.connect(host, user, passwd, db, port, conv=convert) 
    except MySQLdb.Error, e: 
     print "Error connecting %d: %s" % (e.args[0], e.args[1]) 
    return conn 
2

Ich stolperte über das gleiche Problem serialisiert werden: Daten der DATETIME(1) Abrufen von -Typs None zurückgibt.

Einige Forschung ergab MySQLdb-Bug #325. Laut diesem Bug-Tracker ist das Problem immer noch offen (seit über 2 Jahren), aber die Kommentare bieten eine funktionierende Lösung:

In times.py des MySQLdb-Pakets müssen Sie einige Zeilen einfügen Mikrosekunden wie folgt aus:

def DateTime_or_None(s): 
    if ' ' in s: 
     sep = ' ' 
    elif 'T' in s: 
     sep = 'T' 
    else: 
     return Date_or_None(s) 

    try: 
     d, t = s.split(sep, 1) 
     if '.' in t: 
      t, ms = t.split('.',1) 
      ms = ms.ljust(6, '0') 
     else: 
      ms = 0 
     return datetime(*[ int(x) for x in d.split('-')+t.split(':')+[ms] ]) 
    except (SystemExit, KeyboardInterrupt): 
     raise 
    except: 
     return Date_or_None(s) 

def TimeDelta_or_None(s): 
    try: 
     h, m, s = s.split(':') 
     if '.' in s: 
      s, ms = s.split('.') 
      ms = ms.ljust(6, '0') 
     else: 
      ms = 0 
     h, m, s, ms = int(h), int(m), int(s), int(ms) 
     td = timedelta(hours=abs(h), minutes=m, seconds=s, 
         microseconds=ms) 
     if h < 0: 
      return -td 
     else: 
      return td 
    except ValueError: 
     # unpacking or int/float conversion failed 
     return None 

def Time_or_None(s): 
    try: 
     h, m, s = s.split(':') 
     if '.' in s: 
      s, ms = s.split('.') 
      ms = ms.ljust(6, '0') 
     else: 
      ms = 0 
     h, m, s, ms = int(h), int(m), int(s), int(ms) 
     return time(hour=h, minute=m, second=s, microsecond=ms) 
    except ValueError: 
     return None 

Was ich allerdings nicht erklären kann, Ihre ursprüngliche Abfrage ist auf einer Spalte zu arbeiten und nicht auf der anderen Seite .. Vielleicht ist der zweite nicht jede Mikrosekunde-Informationen in ihm?

+0

Warum wurde diese Antwort abgelehnt? Die Tatsache, dass drei Jahre später der Fehler immer noch nicht behoben wurde, war eine interessante Tatsache für mich (und ich glaube, dass es auch für andere sein wird). Außerdem gibt es die Quelle und eine Lösung, die für mich funktionierte. – Fantilein1990

+0

Ich weiß es nicht, Mann. Das sieht für mich vielversprechend aus und ohne Ihre Antwort wäre ich ohne Umgehung geblieben. – thegiffman