Pymysql字段用%s占位符报错

2023-09-23 30 0

前言

本文主要试图使用占位符或其他方法来动态更新字段,达到对多个字段进行批量更新。但是在摸索一段时间后仍没能解决,倒是了解了sql防注入的风险。


我们知道,pymysql批量更新是使用executemany(sql,data)。 当想对多个字段进行批量更新,自然而然想到用这样的形式。

data = [['字段1',123,'admin'],['字段2',234,'admin']]sql = 'update user_table set %s=%s where username =%s'
cur.executemany(sql,data)

这样写报错。

 

mysql中的字段是用 ` (tab键上方的引号)括起来的。用占位符传值这种形式,会自动带上单引号',且pymysql 的占位符并不是 python 的通用占位符。

如果是只需要传值,那么这里的sql是正常的。但如果是表名和key,sql会变成这样:

sql="update "table" set "key"="value"

解决办法:

一、对于批量更新语句

暂时没有找到可以使用 executemany(sql,data) 进行批量更新的办法。

1- 提前将sql语句拼接好。

sql="update" + table + " set " + key + "=%s" # 注意set前后的空格
cursor.execute(sql, (value,))
# cursor.execute(sql, value)

2- 使用%s作为字段占位符,带(参数)传值,有sql注入风险

# 对表名和字段使用了%s占位符,此种写法成功执行了sql语句。
sql = 'update %s set %s="%s"' %(表名,字段名,值)
cursor.execute(sql)# 以下几种对表名和字段使用了%s占位符,在执行sql语句时均报错
# updata = [['字段1','字段1值','用户名'],['字段12','字段2值','用户名']]
# sql = 'update user_table set %s=%s where username =%s'
# cur.executemany(sql,updata)
# cur.execute(sql,updata[0])
# cur.execute(sql,(col_id,cnt,username)) #col_id = '字段1', cnt = '字段1值'
conn.commit()

3- 防sql注入

 a、字典传值

#1- 使用字典传值,不能传表名和字段名
# 以下对字段名进行传值,报错
# sql = 'update user_table set %(col_id)s=%(cnt)s where username =%(name)s'
# data = {'col_id':'counts','cnt':cnt,'name':username}
# cur.execute(sql,data)
# conn.commit()sql = 'update user_table set counts =%(cnt)s where username =%(name)s'
data = {'cnt':cnt,'name':username}
cur.execute(sql,data)
conn.commit()

b、,逗号传值,不要用%

sql = "insert into 表名 (字段名1,字段名2,字段名3,) values (%s,%s,%s)"
cur.execute(sql, (val1,val2,val3))# sql = "insert into 表名 (字段名1,字段名2,字段名3,) values (%s,%s,%s)" %(val1,val2,val3)
# cur.execute(sql) # 有sql注入风险

4- {}.format形式作为表名或字段名占位 

二、对于批量插入语句

用逗号连接将字段列表转成字符串

field_names = ','.join(field_names)

代码编程
赞赏

相关文章

平方和与立方和【HDOJ2007】
求奇数的乘积【HDOJ2006】
求绝对值【HDOJ2003】
计算球体积【HDOJ2002】
1031直方图
1030最难的问题