【问题标题】:Python SQL query has the wrong typePython SQL 查询类型错误
【发布时间】:2020-04-17 18:31:33
【问题描述】:

我想从我的 python 程序中执行一条 SQL 语句。为此,我使用 MySQLdb 库。这是我的代码:

def execute(sql_statement):
    db = MySQLdb.connect("<DatabaseIP>", "<DatabaseUserName>", "<DatabasePassword>", "<DatabaseName>")
    cursor = db.cursor()
    cursor.execute(sql_statement)
    data = cursor.fetchone()
    db.close()
    return data

def look_up_user_id(username, password):
    print(type(username))
    print(type(password))
    sql_statement = "SELECT ID FROM user WHERE name = '" + username + "' AND password = '" + password + "'"
    print(sql_statement)
    return Database.execute(sql_statement)

这是从请求中提取用户名和密码的方法,也是实际调用Database类方法的方法。

@app.route('/auth', methods=['GET'])
def log_in():
    return AuthenticationManager.log_in(request.authorization.username, request.authorization.password)
def log_in(username, password):
    return Database.execute(SQLStatementBuilder.look_up_user_id(username, password))[0]

当我执行print(look_up_user_id("me", "password")) 时,一切都按预期工作,我得到了用户的 ID。但是,当我在基本身份验证标头中使用用户名和密码向我的程序发送 HTTP 请求时,我得到了

File "<PythonPath>\Python\Python38\Lib\site-packages\MySQLdb\cursors.py", line 208, in execute
   assert isinstance(query, (bytes, bytearray))
AssertionError 

这是引发错误的方法

    def execute(self, query, args=None):
        """Execute a query.

        query -- string, query to execute on server
        args -- optional sequence or mapping, parameters to use with query.

        Note: If args is a sequence, then %s must be used as the
        parameter placeholder in the query. If a mapping is used,
        %(key)s must be used as the placeholder.

        Returns integer represents rows affected, if any
        """
        while self.nextset():
            pass
        db = self._get_db()

        if isinstance(query, unicode):
            query = query.encode(db.encoding)

        if args is not None:
            if isinstance(args, dict):
                nargs = {}
                for key, item in args.items():
                    if isinstance(key, unicode):
                        key = key.encode(db.encoding)
                    nargs[key] = db.literal(item)
                args = nargs
            else:
                args = tuple(map(db.literal, args))
            try:
                query = query % args
            except TypeError as m:
                raise ProgrammingError(str(m))
        assert isinstance(query, (bytes, bytearray))
        res = self._query(query)
        return res

look_up_user_id 方法中的两次 print 调用在测试用例和密码和名称中都返回 &lt;class 'str'&gt;

感谢您的帮助!

编辑:添加引发错误的方法

【问题讨论】:

  • 我添加了方法,希望现在更清楚一点。
  • 打印 &lt;class 'str'&gt; 。我现在也将它添加到问题中。
  • 这是我自己的课程,目前只有 log_in 方法,您可以在下面的块中看到。

标签: python database types database-connection assertion


【解决方案1】:

问题在于lookup_user_id 正在返回Database.execute(sql_statement) 的结果,而那个 结果在AuthorizationManager 的返回语句中再次传递给Database.execute。要解决此问题,请让 SQLStatementBuilder 返回 sql_statement。还要注意log_in 视图应该返回一个字符串或类似的。

另外,考虑执行这样的 SQL 语句:

res = cursor.execute("""SELECT id FROM user WHERE name = %s and password = %s""",
                     (username, password))

防止 SQL 注入攻击。

【讨论】:

  • 非常感谢!它现在可以工作了,我会将您的好建议添加到我的代码中。
猜你喜欢
  • 1970-01-01
  • 2013-04-07
  • 1970-01-01
  • 1970-01-01
  • 2019-11-21
  • 1970-01-01
  • 1970-01-01
  • 2015-09-29
相关资源
最近更新 更多