Python SQL запрос имеет неправильный тип - PullRequest
0 голосов
/ 17 апреля 2020

Я хочу выполнить оператор SQL из моей программы python. Для этого я использую библиотеку 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-запрос моей Программе с именем пользователя и паролем в базовом c заголовке аутентификации, я получаю

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

Два вызова print в методе look_up_user_id просто возвращают <class 'str'> в обоих тестовых случаях и для пароля и имени.

Спасибо за любую помощь!

Редактировать: добавлено метод, который вызывает ошибку

1 Ответ

0 голосов
/ 18 апреля 2020

Проблема в том, что lookup_user_id возвращает результат Database.execute(sql_statement), а , что результат снова передается Database.execute в операторе возврата AuthorizationManager. Чтобы это исправить, нужно SQLStatementBuilder return sql_statement. Также обратите внимание, что представление log_in должно возвращать строку или подобное.

Кроме того, рассмотрите возможность выполнения SQL операторов, таких как:

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

, чтобы предотвратить SQL атаки с использованием инъекций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...