当我用实际列名替换列变量时,这是有效的。但我需要一个变量。当我使用变量时,我得到一个MySQL语法错误。字段可以变量吗?如果是,那么错误在哪里?
conn = self.create_connection()
cur = conn[0]
db = conn[1]
cur.execute('''
UPDATE coefficients
SET %s = %s
WHERE coef_id = %s
''' , (sql_col_name, fgi, ici))
db.commit()
好的,这是追溯:
raise errorclass, errorvalue
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''base_rpm' = 3500 WHERE coef_id = 460' at line 1")
答案 0 :(得分:3)
问题在于execute
方法中的参数替换仅用于数据 - 正如您所发现的那样。
这在documentation中并不十分明确,但它是大多数数据库驱动程序实现它的方式。
重要的是要注意execute
和executemany
方法中参数替换的意图是将Python对象格式化为数据库的字符串,并应用转义和引号,以便SQL注入成为很难(如果不是不可能的话)没有人担心几个地方放弃逃跑。
当您需要使用变量列名(或改变SQL语句的其他部分)时,需要使用Python的字符串格式化方法格式化字符串 - 并以合适的方式保留结果字符串在第二次替换中用作数据替换的合适参数(以便类型转换和引用仍然由驱动程序执行)。
为避免必须转义参数本身的%s
条目,您可以使用与%
运算符不同的字符串插值方法,例如,较新的format
字符串方法:< / p>
cur.execute('''
UPDATE coefficients
SET {} = %s
WHERE coef_id = %s
'''.format(sql_col_name) ,
(fgi, ici))
此示例显示了使您的示例正常工作的最简单方法 - 只需将其写入代码中,以便易于阅读和维护 - 例如,为语句使用额外变量,并在之前调用format
调用execute
的行。但那只是风格。