1

我对连接器/python 执行插入查询有一点问题。

我有将数据插入数据库的功能。参数数据是元组列表:[(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()

查询本身起作用,在 self.__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() 出错了。

4

2 回答 2

4

仅用%s作 中的参数标记query。不要使用%d

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

%sformat DB-API 中定义的参数样式。%s它与字符串格式的含义不同。

要使用的正确参数样式取决于数据库驱动程序。MySQLdb 使用%s. 其他数据库驱动程序,例如oursqlsqlite3使用?.

于 2013-08-18T18:17:09.963 回答
2

您不应该使用SQL%d参数。坚持%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 文档

paramstyle
字符串常量,说明接口期望的参数标记格式的类型。设置为'format'= ANSI Cprintf格式代码,例如'...WHERE name=%s'. 如果 conn.execute() 使用了映射对象,那么接口实际上使用了'pyformat'= Python 扩展格式代码,例如'...WHERE name=%(name)s'. 但是,API 目前不允许在 paramstyle 中指定一种以上的样式。

当然,使用%sSQL 参数与 Python 字符串格式化很相似,但并不相同。

于 2013-08-18T18:17:12.277 回答