2013-08-18 6 views
1

У меня есть небольшая проблема с выполнением запроса вставки/коннектора/python.Коннектор/python executemany NoneType

У меня есть функция для вставки данных в базу данных. Довод данные список кортежей: [(2652884, 'http://www.example.com/', '5.0.5.239', 1), .....]

def insert_url(self, data): 

    query = "INSERT INTO `sp_urls` (`parent_id`, `url`, `version`, `hits`) VALUES (%d, %s, %s, %d) ON DUPLICATE KEY UPDATE url=url"   


    try: 
     cursor = self.__cnx.cursor() 
     cursor.executemany(query, data) 
    except (mysql.connector.errors.IntegrityError) as err: 
     print("Query syntax error:", err, file=sys.stderr) 
    except (mysql.connector.errors.ProgrammingError) as err: 
     print("Programming err:{0}".format(err)) 
    finally: 
     cursor.close() 

Запрос сам работает в себя .__ CNX инициализируется соединение , Вот отслеживающий:

File "sdi/database/DbValidator.py", line 91, in process_records 
    self.__driver.insert_url(urldata) 
    File "/home/david/workspace/stickydi/sdi/database/MySQLDriver.py", line 87, in insert_url 
    cursor.executemany(query, data) 
    File "/usr/lib/python3/dist-packages/mysql/connector/cursor.py", line 492, in executemany 
    return self._batch_insert(operation,seq_params) 
    File "/usr/lib/python3/dist-packages/mysql/connector/cursor.py", line 428, in _batch_insert 
    fmt = m.group(1).encode(self._connection.charset) 
AttributeError: 'NoneType' object has no attribute 'group' 

У меня есть один очень похожий метод, и он хорошо работает, я просто не могу видеть, почему executemany() идет не так.

ответ

2

Вы должны не использовать %d для параметров SQL. Придерживайтесь %s и пусть коннектор MySQL обрабатывать типы:

query = """\ 
    INSERT INTO `sp_urls` (`parent_id`, `url`, `version`, `hits`) 
    VALUES (%s, %s, %s, %s) 
    ON DUPLICATE KEY UPDATE url=url 
    """ 

Цитируя Python-MySQL documentation:

paramstyle
Строка константа, тип маркера параметра форматирования ожидаемый интерфейс. Установите значение 'format' = коды формата ANSI C printf, например. '...WHERE name=%s'. Если для conn.execute() используется объект сопоставления, то на самом деле интерфейс использует 'pyformat' = коды расширенного формата Python, например. '...WHERE name=%(name)s'. Однако API в настоящее время не позволяет специфицировать более одного стиля в paramstyle.

Предоставлено, используя %s для параметров SQL схоже с форматированием строки Python, но это не то же самое.

+0

Я читал об условном обозначении форматирования очень коротко некоторое время назад, и я помню только, что это конвенция типа C, поэтому я подумал, что это работает и с% d. Я был явно неправ, спасибо за объяснение. – dakov

4

Используйте только маркер параметра query. Не используйте %d:

query = """ 
    INSERT INTO `sp_urls` (`parent_id`, `url`, `version`, `hits`) 
    VALUES (%s, %s, %s, %s) ON DUPLICATE KEY UPDATE url=url"""   

%s является formatparamstyle defined in the DB-API. Он не имеет то же значение, что и %s в форматировании строк.

Правильный параметр для использования зависит от драйвера базы данных. MySQLdb использует %s. Другие драйверы для базы данных, такие как oursql и sqlite3?.