在1个字符串中执行超过1000个插入语句

时间:2014-04-30 14:41:28

标签: python mysql sql mysql-python

我认为这个很简单,但无论出于什么原因,当脚本完成时,数据都不在表中。我正在生成一个超过1000个查询的字符串,目前是1131,它们由";"分隔。

此字符串由简单的for循环创建:

query = ""

for: #loop condition
    query += "INSERT INTO Results (col1, col2, col3, col4, pass) VALUES ('%s', %s, %s, %s, 0);" % (val1, val2, val3, val4)
logger.debug("SQL Query = %s" % query)

try:
    cursor.execute(query, multi=True)
except MySQLdb.Error, e:
    try:
        logger.error("MySQL Error [%d]: %s" % (e.args[0], e.args[1]))
        dbinit.cnx.rollback()
        cursor.close()
        dbinit.cnx.close()
    except IndexError:
        logger.error("MySQL Error: %s" % str(e))
        dbinit.cnx.rollback()
        cursor.close()
        dbinit.cnx.close()

dbinit.cnx.commit()
cursor.close()
dbinit.cnx.close()

我没有收到任何错误,当我打印字符串时,它打印得很好。我甚至可以复制/粘贴打印的内容,并一次运行sql命令,它运行得很好,所以我不会有任何错误的查询。任何帮助表示赞赏,因为我很难过。我知道还有其他方法可以解决这个问题,但是如果有人也可以解释为什么这个没有工作,那么我可以学习,也会受到赞赏!

更新:Mike的回答大部分都是正确的,但我只是想用我的代码最终看起来像这样的帖子更新这篇文章。

queryData=[]
for: #condition
    queryData.append((val1, val2, val3, val4, 0))

while len(queryData) != 0:
    cursor.executemany("INSERT INTO Results (col1, col2, col3, col4, pass) VALUES (%s, %s, %s, %s, %s)", queryData[:999])
    del queryData[:999]
dbinit.cnx.commit()

1 个答案:

答案 0 :(得分:2)

看起来你是以错误的方式解决这个问题。 cursor.execute()接受一个查询,准备它并使用您提供的数据执行它。在这一行

cursor.execute(query, multi=True)

您已省略第二个params参数,因此无法执行任何数据。

您似乎将1000多个查询组合为单个字符串。您也许可以使用cursor.query()执行此操作,但是(如果它有效)将导致服务器解析并准备1000次以上相同的查询,这不是有效的。在任何情况下,许多MySQL类都特别禁止以这种方式组合多个查询。

您需要cursor.executemany(query, data)构建单个查询,具有多个值集,每个data一行。

我不是Python开发人员,而且我无法确定您从哪里获取数据,但这是MySQL reference的示例,经过重新设计:

data = [
  ('col1-1', 1,2,3),
  ('col1-2', 4,5,6),
  ('col1-3', 7,8,9),
]
stmt = "INSERT INTO Results (col1, col2, col3, col4, pass) VALUES ('%s', %s, %s, %s, 0)"
cursor.executemany(stmt, data)

您可以添加自己的异常处理。希望这能让你开始。

注意:您可以通过这种方式插入的值集数量没有限制,但 是您可以创建的字符串长度的限制,默认情况下是1MB。如果您的要求超过此要求,您可以将插入批处理,例如,一次500个并运行多个查询(3个查询仍然优于1500!)或查看cursor.MySQLCursorPrepared类,该类解析查询一次并执行您发送的每组数据。