【问题标题】:Removing quotes from mysql query in Python在 Python 中从 mysql 查询中删除引号
【发布时间】:2016-07-20 06:15:23
【问题描述】:

我知道过去有人问过这个问题,但彻底搜索似乎并没有解决我的问题。我可能只是缺少一些简单的东西,因为我是 mysql 提供的 Python-mysql 连接器的新手。

我有一个访问 mysql 数据库的 Python 脚本,但我在从查询中删除引号时遇到了问题。这是我的代码:

import mysql.connector

try:
    db = mysql.connector.connect(user='root', password='somePassword', host='127.0.0.1', database='dbName')
    cursor = db.cursor()
    query = "select * from tags where %s = %s"
    a = 'tag_id'
    b = '0'
    cursor.execute(query, (a, b))
    print cursor
    data = cursor.fetchall()
    print data
except mysql.connector.Error as err:
    print "Exception tripped..."
    print "--------------------------------------"
    print err

cursor.close()
db.close()

我的数据库设置正确(我将很快证明)。

我对这个程序的输出是:

MySQLCursor: select * from tags where 'tag_id' = '0'
[]

然而,当我将查询更改为不使用变量时,例如:

cursor.execute("select * from tags where tag_id = 0")

那么我的输出变成:

MySQLCursor: select * from tags where tag_id = 0
[(0, u'192.168.1.110')]

对我来说,这意味着我的光标查询之间的唯一区别是引号。

如何从查询中删除它们?

提前致谢。

【问题讨论】:

  • 这到底是怎么回事?
  • where条件只能使用参数,即... WHERE tag_id = %s
  • 如果您想删除引号,只需执行cursor.execute(query%(a, b))
  • @dermen 这不是一个好主意,因为它使用 Python 的字符串格式而不是参数化查询引擎,这是一种非常糟糕的做法。
  • @dermen 我不认为%d 在这个库中有效。它应该保留为%s

标签: python mysql


【解决方案1】:

我个人认为这段代码是正确且安全的,但是您应该非常怀疑在没有自己仔细审查或(更好)在安全专家的帮助下使用这样的代码。我没有资格成为这样的专家。

我改变了两件重要的事情:

  1. 我将b = '0' 更改为b = 0,所以它以数字而不是带引号的字符串结束。 (这部分很容易解决。)
  2. 我跳过了列名的内置参数化并将其替换为我自己对 mysql-connector 内置的转义/引用的轻微修改。这是应该让你停下来的可怕部分。

下面的完整代码,但如果列名是用户输入,请再次注意这一点!

import mysql.connector

def escape_column_name(name):
    # This is meant to mostly do the same thing as the _process_params method
    # of mysql.connector.MySQLCursor, but instead of the final quoting step,
    # we escape any previously existing backticks and quote with backticks.
    converter = mysql.connector.conversion.MySQLConverter()
    return "`" + converter.escape(converter.to_mysql(name)).replace('`', '``') + "`"

try:
    db = mysql.connector.connect(user='root', password='somePassword', host='127.0.0.1', database='dbName')
    cursor = db.cursor()
    a = 'tag_id'
    b = 0
    cursor.execute(
        'select * from tags where {} = %s'.format(escape_column_name(a)),
        (b,)
    )
    print cursor
    data = cursor.fetchall()
    print data
except mysql.connector.Error as err:
    print "Exception tripped..."
    print "--------------------------------------"
    print err

cursor.close()
db.close()

【讨论】:

  • 谢谢,这成功了!我的最终代码不会将用户输入用于列名,但对于测试它会非常方便。感谢您的回复和 sql 注入警告,非常感谢!
【解决方案2】:

我在使用 pymysql 时遇到了类似的问题,并显示了我的工作代码 here,希望这会有所帮助。

我所做的是覆盖类'pymysql.connections.Connection'中的转义方法,这显然会在你的字符串周围添加“'”。

最好显示我的代码:

from pymysql.connections import Connection, converters


class MyConnect(Connection):
    def escape(self, obj, mapping=None):
        """Escape whatever value you pass to it.

        Non-standard, for internal use; do not use this in your applications.
        """
        if isinstance(obj, str):
            return self.escape_string(obj)  # by default, it is :return "'" + self.escape_string(obj) + "'"
        if isinstance(obj, (bytes, bytearray)):
            ret = self._quote_bytes(obj)
            if self._binary_prefix:
                ret = "_binary" + ret
            return ret
        return converters.escape_item(obj, self.charset, mapping=mapping)


config = {'host':'', 'user':'', ...}
conn = MyConnect(**config)
cur = conn.cursor()

【讨论】:

    猜你喜欢
    • 2022-01-16
    • 1970-01-01
    • 2014-03-03
    • 2017-10-08
    • 2018-08-02
    • 1970-01-01
    • 2020-02-28
    • 2015-04-21
    • 2017-01-28
    相关资源
    最近更新 更多