mysqldb преобразует данные метки времени в None

Я использую MySQLdb для общения с базой данных mysql, и я могу динамически извлекать все наборы результатов.

Моя проблема в том, что как только я получаю набор результатов, есть пара столбцов, которые объявлены как временные метки в mysql, но когда они извлекаются, они превращаются в None.

У меня есть два столбца, оба объявлены временными метками, но один возвращает правильные данные, а другой возвращает None. И utime, и enddate объявляются временными метками, но utime не возвращает правильный результат, а enddate возвращает.

['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

person ronak    schedule 14.03.2013    source источник


Ответы (2)


Наконец, после того, как никто не ответил или не попытался найти дополнительную информацию, я продолжил искать другие решения и обнаружил, что библиотека MySQLdb преобразует типы данных из sql в python, и есть ошибка, которая не преобразует метку времени.

Я до сих пор не знаю, почему один из них конвертируется, а другой нет. Если кто-то может понять это, пожалуйста, обновите это.

Но вот модификация, которую нужно сделать при подключении к базе данных mysql. MySQLdb не может сериализовать объект даты и времени Python

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
person ronak    schedule 14.03.2013

Я столкнулся с той же проблемой: получение данных типа DATETIME(1) возвращает None.

Некоторые исследования выявили ошибку MySQLdb №325. Согласно этому трекеру ошибок, проблема все еще открыта (уже более 2 лет), но комментарии предоставляют рабочее решение:

В файле times.py пакета MySQLdb вам нужно вставить несколько строк для обработки микросекунд следующим образом:

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

Однако я не могу объяснить, что ваш исходный запрос работает с одним столбцом, а не с другим. Может быть, во втором нет микросекундной информации?

person Fantilein1990    schedule 06.09.2016
comment
Почему этот ответ был отклонен? Тот факт, что три года спустя ошибка все еще не исправлена, был интересным фактом для меня (и, я думаю, будет интересен и для других). Кроме того, в нем указаны источник и решение, которое сработало для меня. - person Fantilein1990; 08.09.2016
comment
Я не знаю, чувак. Это выглядит многообещающе для меня, и без вашего ответа я бы остался без обходного пути. - person thegiffman; 22.03.2017
comment
Вы, ребята, установили MySQLdb через pip? Моя установка py2.7 (с 2014 года) имеет код, идентичный вашему сообщению. Моя установка py3.6 (с 2017 года) имеет другой код, но по-прежнему обрабатывает микросекунды. - person user2426679; 14.09.2018