我有以下代码
conn = MySQLdb.connect(server, user, password, database, autocommit=True, charset='utf8')
for e in list_to_updpate:
nid = e[0]
vid = e[1]
text = e[2]
delta = e[3]
deleted = e[4]
langcode = e[5]
to_update = e[6]
if (to_update == 1):
with conn.cursor() as cursor:
cursor.execute("""update node__body set body_value=%s
where entity_id=%s AND revision_id=%s AND
delta=%s AND deleted=%s AND langcode=%s;""" ,
(MySQLdb.escape_string(text) , int(nid),
int(vid), int(delta), int(deleted), langcode, ))
conn.commit()
conn.close()
我有要更新的条目列表,文本是长文本,可以包含UTF8表中的任何内容。
当我运行代码时,我注意到两件事:
在某些时候,它会因错误而崩溃:
_mysql_exceptions.OperationalError: (1242, 'Subquery returns more than 1 row')
我无法掌握它,我确信只有一行得到更新,因为根据表定义,主键定义为(entity_id,revision_id,delta,deleted,langcode)
注意:pymysql和python3.6上的MySQL-client重复此行为
此致 T
答案 0 :(得分:1)
找到答案:
事实证明,为了匹配mysql数据库的LONGTEXT,应该使用io.String()对象来传递文本。否则它的行为不符合预期。大多数情况下,您可以期望将一个简单的字符串映射到varchar,该字符串应该是最大长度。请注意,因为varchar可以是LONG TEXT的子集,所以如果查询提交,则不会引发错误,如果将输入提交到DB,则会裁剪输入。为什么在这个特殊情况下,它从未承诺(见问题中的讨论)对我来说仍然不清楚。现在工作代码:
conn = MySQLdb.connect(server, user, password, database, autocommit=True, charset='utf8')
for e in list_to_update:
cursor = conn.cursor()
nid = e[0]
vid = e[1]
text = e[2]
delta = e[3]
deleted = e[4]
langcode = e[5]
to_update = e[6]
if to_update == 1:
cursor.execute(
"update node__body set body_value=%s where entity_id=%s AND revision_id=%s AND delta=%s AND deleted=%s AND langcode=%s",
(io.StringIO(text), nid, vid, delta, deleted, langcode))
conn.commit()
cursor.close()
conn.close()
注意这是Python3。对于Python2,请使用StringIO.String()
希望有所帮助,
托多尔
答案 1 :(得分:0)
在发布代码之前,我想指出一些事项。
首先,不需要escape_string,因为execute会为你做,只要你在元组中包含参数作为第二个元素。
我怀疑你的问题在光标周围。似乎在提交任何内容之前正在打开,使用和关闭。
如果没有任何元素违反了更新列表中所有元素所需的光标,我建议采用这种方法。
conn = MySQLdb.connect(server, user, password, database, autocommit=True, charset='utf8')
cursor = conn.cursor()
for e in list_to_update:
nid = e[0]
vid = e[1]
text = e[2]
delta = e[3]
deleted = e[4]
langcode = e[5]
to_update = e[6]
if to_update == 1:
cursor.execute("update node__body set body_value=%s where entity_id=%s AND revision_id=%s AND delta=%s AND deleted=%s AND langcode=%s" ,
(text , nid, vid, delta, deleted, langcode))
conn.commit()
cursor.close()
conn.close()
如果您只需要在一端进行一次提交,则只需编辑提交行,删除一个缩进。
另请注意,我已添加cursor.close
,因为我没有使用with
方法。