Параметризованные запросы

Тренажер по Python для пользователей с начальным уровнем подготовки.

Тренажер по Python

В этом уроке мы изучим одну из самых важных тем при работе с базами данных в Python — **параметризованные запросы**. Это ключевой механизм защиты от SQL-инъекций. Вы научитесь правильно передавать данные в SQL-запросы, используя плейсхолдеры (заполнители) вместо форматирования строк. Мы разберем разницу между безопасными и небезопасными методами, научимся формировать кортежи параметров и применять их в методе execute(). Задания построены от простых концепций к написанию рабочего кода.

Список тем

Безопасно или Уязвимо?

id: 40179_task1

Распределите примеры вызовов SQL-запросов по двум категориям: "Безопасно (Параметризация)" и "Уязвимо (SQL-инъекция)". Помните, что использование f-строк или конкатенации для подстановки значений в SQL — это плохая практика.

Перетяните элементы в соответствующие блоки
Безопасно (Параметризация)
Уязвимо (SQL-инъекция)
cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
cursor.execute("INSERT INTO log VALUES (?)", (data,))
query = "SELECT * FROM items WHERE name = '" + name + "'"
cursor.execute(query)
cursor.execute("UPDATE stats SET count = ? WHERE label = ?", (10, 'hits'))
Сообщения
Проверить
Показать подсказку

Элементы параметризованного запроса

id: 40179_task2

Сопоставьте элементы кода (слева) с их ролью в параметризованном запросе (справа).

Сопоставьте строки в правой части с соответствующими строками в левой по порядковому номеру
Символ `?` в строке SQL
`(var,)` (с запятой)
Второй аргумент в execute()
Плейсхолдер (заполнитель)
Кортеж из одного элемента
Данные для подстановки
Сообщения
Проверить
Показать подсказку

Ошибка в передаче параметров

id: 40179_task3

В данном коде есть распространенная ошибка при передаче одного параметра. Метод `execute` ожидает последовательность (кортеж или список) вторым аргументом, даже если параметр всего один. Найдите и исправьте строку с ошибкой.

Найдите ошибку и исправьте
product_id = 42
# Ошибка: пропущена запятая для создания кортежа
cursor.execute("SELECT price FROM goods WHERE id=?", (product_id))
result = cursor.fetchone()
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Безопасная вставка данных

id: 40179_task4

Допишите код для добавления нового пользователя. Используйте параметризацию, чтобы избежать ошибок и уязвимостей. Данные для вставки находятся в переменных `name` и `age`.

Заполните пропуски
name = "Alice"
age = 30

# Вставляем 2 значения, нужны 2 плейсхолдера
cursor.execute("INSERT INTO users (name, age) VALUES (input1S, input2S)", input3S)
conn.commit()
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Поиск с фильтрацией

id: 40179_task5

Соберите код, который ищет книги, цена которых меньше заданной переменной `max_price`. Используйте безопасный синтаксис `sqlite3`.

Нужно правильно расставить в пропуски предложенные варианты
max_price = 500
sql = "SELECT title FROM books WHERE input1S"
cursor.execute(input2S, input3S)
price < ?
sql
(max_price,)
price < {max_price}
(max_price)
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Последовательность обновления данных

id: 40179_task6

Расставьте строки кода в правильном порядке, чтобы обновить email пользователя. Обратите внимание на порядок: подготовка данных -> выполнение запроса -> фиксация изменений.

Расставьте строки в правильном порядке
new_email = 'new@example.com'
user_id = 101
cursor.execute("UPDATE users SET email = ? WHERE id = ?", (new_email, user_id))
conn.commit()
Сообщения
Проверить
Показать подсказку

Безопасная регистрация пользователя

id: 40179_task7

Соберите функцию `register_user`, которая принимает логин и пароль и безопасно вставляет их в базу данных. Остерегайтесь небезопасного варианта с f-строкой (decoy).

Перетяните в правильном порядке строки из одного блока в другой
def register_user(login, password):
    query = "INSERT INTO users (login, pass) VALUES (?, ?)"
    cursor.execute(query, (login, password))
    conn.commit()
    query = f"INSERT INTO users VALUES ('{login}', '{password}')"
    cursor.execute(query)
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Что произойдет при выполнении?

id: 40179_task8

Проанализируйте код. В таблице `products` есть товар 'Apple' с ценой 100. Мы пытаемся обновить цену. Какой будет результат выполнения этого кода?

Выберите правильный вариант ответа
new_price = 120
# Ошибка: передано просто число, а не кортеж (120,)
try:
    cursor.execute("UPDATE products SET price=? WHERE name='Apple'", (new_price))
    print("Success")
except TypeError:
    print("Error: Parameters must be a sequence")
except Exception as e:
    print("Other Error")
Сообщения
Проверить
Показать подсказку
НайтиКурс.Ру