【问题标题】:Using a variable as field name in MySQLdb, Python 2.7在 MySQLdb,Python 2.7 中使用变量作为字段名
【发布时间】:2017-01-07 02:51:16
【问题描述】:

当我用实际的列名替换列变量时,这有效。但是,我确实需要一个变量。当我使用一个变量时,我得到一个 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")

【问题讨论】:

  • 我没有使用 MySQLdb,但我使用了带有 Redshift 数据库的 psycopg2,并且要在 sql 语句中使用变量,您必须定义一个 sql 字符串并将 sql 字符串传递给执行命令。例如:sql = "Update coefficients SET %s = %s WHERE coef_id = %s"cur.execute(sql) 如果未以这种方式定义,则将文字 %s 传递给查询。
  • 我不会发布作为答案,因为我自己在 SQLite 中做这件事感觉不舒服(我觉得这很老套,如果有人告诉我我错了,也许我也会受益......)但您可以单独形成查询,例如query = "UPDATE something SET {} = %s".format('hello') 然后print query % 'goodbye'。在这种情况下,format 的使用不会影响您预先形成的字符串中的%s,因此您可以分两部分创建它。
  • 我无法编辑我之前的评论,但当然要获取字符串中的变量,您需要在 sql 语句中使用类似的内容。 sql = "Update coefficients SET {1} = {2} WHERE coef_id = {3}".format(sql_col_name, fgi, ici) 或者您喜欢的任何格式设置,只要将它们添加到字符串中即可。
  • @BobDunakey 但这是标准做法吗?我总是在 SQLite 中执行之前形成字符串,但这只是由于严重的时间压力,它关闭了您无法在执行时分配 = 剩下的东西的错误。我从来没有接受过它,这肯定有一个标准功能吗?
  • @BobDunakey 实际上您的答案可能会更深入,因为您使用format 分配值(在= 的RHS 上)并绕过减少SQL 机会的占位符注射?

标签: python python-2.7 mysql-python


【解决方案1】:

问题在于 execute 方法中的参数替换仅用于数据 - 正如您发现的那样。 这在documentation 中并不十分明确,但它是大多数数据库驱动程序实现它的方式。

需要注意executeexecutemany方法中参数替换的意图是将Python对象格式化为数据库的字符串,并应用转义和引号,以便SQL注入变得困难(如果不是不可能),而不必担心在哪里放置转义符。

当您需要使用可变列名(或改变 SQL 语句的其他部分)时,需要使用 Python 的字符串格式化方法格式化字符串 - 并以合适的方式保留生成的字符串以用作合适的数据替换的参数,在第二次替换中(因此类型转换和引用仍然由驱动程序执行)。

为避免必须为参数本身转义%s 条目,您可以使用与% 运算符不同的字符串插值方法,例如,较新的format 字符串方法:

  cur.execute('''
                    UPDATE coefficients
                    SET {} = %s 
                    WHERE coef_id = %s

                '''.format(sql_col_name) ,
                (fgi, ici)) 

此示例显示了使您的示例工作的最简单方法 - 只需将其编写在代码中,使其易于阅读和维护 - 例如,为语句使用额外的变量,并在行之前调用 format打电话给execute。但这只是风格。

【讨论】:

  • 赞成,感谢您在 cmets 中确认我的方法。很长一段时间以来,这一直是令人不适的根源,但正如您所说,它在文档中并不明确:)
  • 完美!非常感谢大家的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-27
  • 2018-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-20
相关资源
最近更新 更多