Модуль 20

From SQL to Real Applications

Ось урок, створений спеціально за твоїм запитом, у стилі CS50 та українською мовою.


🎓 Тема: From SQL to Real Applications (Як "подружити" код із базою даних)

Привіт, друзі! 👋

Ви вже знаєте, як написати SELECT * FROM users у терміналі, і це чудово. Ви відчуваєте цю силу, коли база даних слухняно віддає вам таблиці. Але зупиніться на секунду і подумайте: коли ви востаннє користувалися Instagram або TikTok через термінал, вводячи SQL-запити?

Ніколи, правда ж?

Сьогодні ми знесемо стіну між "сухим" SQL і живим світом програм. Ми навчимося керувати базою даних прямо з вашого коду на Python (або будь-якої іншої мови). Поїхали! 🚀


1. 🔥 Вступ: Проблема та мотивація

Уявіть, що ви — шеф-кухар (це база даних). У вас на кухні є всі інгредієнти (дані). Але клієнти в залі (користувачі) не можуть просто забігти на кухню і почати ритися в холодильнику. Це був би хаос! 🍳

Потрібен офіціант. Ваша програма (код) — це офіціант.

Він бере замовлення у клієнта ("Хочу побачити свій профіль"), йде на кухню, каже шефу спеціальною мовою ("SELECT..."), забирає страву (дані) і гарно подає її клієнту на екран.

Питання до вас:

Що станеться, якщо офіціант просто крикне на кухню все, що сказав клієнт, не перевіривши це? А якщо клієнт "замовить" підпалити кухню?

Без інтеграції SQL у код (Python, JS, C#) ваші дані — це просто мертвий вантаж. Сьогодні ми навчимося писати цього "офіціанта".


2. 🧠 Теоретична база (Що там "під капотом"?)

Щоб програма "поговорила" з базою даних, магії не достатньо. Потрібен Драйвер (Driver) або Адаптер.

🛠 Як це працює (логіка процесу):

  1. Connect (Дзвінок): Ваша програма "дзвонить" базі даних.
    • Приклад: "Алло, це PostgreSQL? Я — Python-скрипт, ось мій пароль. Впустиш?"
  2. Cursor (Вказівник): Це ніби ваш палець, який біжить по рядках результату.
    • Ви надсилаєте запит.
    • База готує відповідь у пам’яті.
    • Курсор дозволяє вам брати дані по шматочках або все одразу.
  3. Execute (Виконання): Ви надсилаєте SQL як звичайний текст (string) через цей канал зв'язку.
  4. Commit (Фіксація): Якщо ви щось змінили (INSERT, UPDATE), ви маєте сказати "Зберегти!". Інакше, коли ви покладете слухавку, база забуде ваші зміни.

📌 Що треба запам'ятати залізно:

  • SQL у коді — це просто рядки тексту. Програмі все одно, що там написано, поки вона не відправить це в БД.
  • Ніколи не довіряйте користувачу. Це правило №1 безпеки (про це далі).

3. 🧪 Приклади: Від "Привіт, світ" до хакерської атаки

Для прикладів візьмемо Python (бо це мова CS50), але логіка ідентична для Java, JS чи C++.

Етап 1: Найпростіший запит

Уявіть, що ми підключили бібліотеку cs50 або sqlite3. Чого ви очікуєте, якщо ми просто попросимо список усіх студентів?

# db - це наше підключення до бази
rows = db.execute("SELECT name, house FROM students")

for row in rows:
    print(f"{row['name']} живе у гуртожитку {row['house']}")

Що відбулося? Ми відправили рядок SQL. База повернула нам список (list) словників (dictionaries). Ми просто пробіглися по ньому циклом. Просто? Так.


Етап 2: Реальна проблема (Інтерактивність)

Тепер ми хочемо знайти студентів конкретного гуртожитку, який вводить користувач.

Наївний (і небезпечний) підхід:

house_input = input("Введіть гуртожиток: ") # Користувач вводить: Gryffindor

# ❌ ТАК РОБИТИ НЕ МОЖНА!
query = f"SELECT * FROM students WHERE house = '{house_input}'"
rows = db.execute(query)

Ми просто "склеїли" рядок. Якщо користувач чемний, це спрацює.


Етап 3: SQL Injection (Чому склеювати рядки — зло) 💀

А що, якщо користувач — хакер? Замість Gryffindor, він вводить: ' OR '1'='1

Наш запит перетворюється на:

SELECT * FROM students WHERE house = '' OR '1'='1'

Результат: 1=1 завжди правда. База даних віддасть ВСІХ студентів, навіть прихованих. А якщо хакер напише ; DROP TABLE students; --? Вітаю, ви втратили базу даних. Це називається SQL Injection.


Етап 4: Як роблять профі (Prepared Statements) ✅

Ми використовуємо плейсхолдери (заповнювачі). Ми кажемо базі: "Ось шаблон запиту, а ось дані окремо. Сама розберися, щоб це було безпечно".

house_input = input("Введіть гуртожиток: ")

# Зверніть увагу на знак питання (?)
rows = db.execute("SELECT * FROM students WHERE house = ?", house_input)

Чому це круто: База даних тепер знає: "Ага, все, що прийшло замість ? — це просто текст, а не команда". Навіть якщо там буде команда видалення таблиці, база сприйме її як дивну назву гуртожитку.


4. 🛠 Практична частина

Час забруднити руки кодом! Уявіть, що у вас є таблиця products (id, name, price).

Завдання 1: Читання Напишіть код, який запитує у користувача максимальну ціну і виводить усі товари, дешевші за цю суму. (Підказка: використовуйте WHERE price < ?)

Завдання 2: Виправ помилку Джуніор написав код для реєстрації нового юзера:

username = input("Name: ")
db.execute(f"INSERT INTO users (name) VALUES ('{username}')")

Чому це погано і як це переписати з ? або %s?

Завдання 3: "А що, якщо..." Напишіть код, який оновлює ціну товару (UPDATE). Питання: Що станеться, якщо ви забудете зробити commit (якщо ваша бібліотека не робить авто-коміт)? Чи побачать нову ціну інші користувачі?

Завдання 4: Міні-кейс Створіть просту систему логіну. 1. Запитайте login та password. 2. Зробіть SELECT * FROM users WHERE username = ? AND password = ?. 3. Якщо список результатів не порожній — виведіть "Welcome!". Інакше — "Access Denied".


5. 💡 Мислення як у розробника

Як відрізнити новачка від профі в цій темі?

  1. Параноя — це добре. Досвідчений розробник ніколи не довіряє вводу користувача. Він завжди використовує плейсхолдери (? або %s), навіть якщо впевнений, що дані безпечні.
  2. Ресурси не безкінечні. Новачок відкриває з'єднання з БД (connect), робить запит і... забуває закрити. З часом база скаже "Досить, у мене ліміт підключень" і впаде.
    • Порада: Завжди закривайте з'єднання або використовуйте контекстні менеджери (with db.connect()...).
  3. Логіка не в базі, але і не тільки в коді. Не тягніть усю таблицю в Python, щоб відфільтрувати 5 рядків. Нехай база фільтрує (WHERE), а Python обробляє результат. База робить це швидше.

6. 🧩 Підсумок

Отже, що ми сьогодні зробили? * Ми зрозуміли, що код і база даних — це дві різні держави, а ми будуємо між ними міст. * Ми навчилися передавати змінні в SQL-запити безпечно (прощавай, SQL Injection!). * Ми побачили, що SQL всередині Python/Java — це потужний інструмент для створення реальних додатків.

Що ви тепер вмієте: Ви можете написати скрипт, який реєструє користувачів, шукає товари або аналізує дані, не відкриваючи консоль бази даних.

🔍 Тизер наступного уроку: Писати SQL у коді (SELECT * FROM...) — це круто, але іноді втомлює. А що, якби ми могли працювати з таблицями бази даних так, ніби це звичайні об'єкти (класи) у коді? Без жодного рядка SQL? Наступного разу ми поговоримо про ORM (Object-Relational Mapping). Це як автопілот після того, як ви навчилися водити на "механіці".

А поки що — практикуйтесь і не забувайте про WHERE!


Це був CS50. Побачимось! 👋