Давайте пригадаємо, що таке CRUD—Створення (Create), читання (Read), оновлення (Update) та видалення (Delete) — це базові операції, які ми виконуємо при роботі з базою даних. Ці чотири операції складають основу будь-якого веб-застосунку, від блогів до інтернет-магазинів.
Ось приклад із реального життя. Уявіть, що ви менеджер у книжковому магазині. Ви додаєте нові книги в каталог (Create), перевіряєте, чи є потрібна книга в наявності (Read), оновлюєте ціну книги (Update) і прибираєте з каталогу книги, які вже років 10 як розпродані (Delete).
SQLAlchemy якраз допомагає нам стати такими собі "менеджерами" для бази даних, але без важких коробок.
Основи роботи з CRUD у SQLAlchemy
У SQLAlchemy є зручний інтерфейс для виконання CRUD-операцій. Центральним елементом у ньому є клас Session, який керує всіма взаємодіями з базою даних.
Session працює як посередник між нашими моделями і реальною базою даних. Сесія дбає про виконання транзакцій і підтримку консистентності даних.
Перед тим як ми почнемо виписувати SQL-запити, важливо правильно налаштувати сесію. Якщо ви пропустили налаштування бази даних і підключення SQLAlchemy, повертайтеся до попередніх лекцій. А для тих, хто вже тут:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
# Створюємо engine
DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(DATABASE_URL)
# Створюємо фабрику сесій
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Сесія готова. Тепер ми можемо її використовувати для операцій з базою даних.
Створення записів (Create)
Щоб додати новий запис у базу, потрібно:
- Створити об'єкт моделі з потрібними даними.
- Додати його до поточної сесії.
- Зафіксувати зміни (commit).
Ось приклад додавання нового користувача в таблицю users:
from models import User # Припустимо, ви вже створили модель User
# Створюємо сесію
db = SessionLocal()
# Створюємо об'єкт користувача
new_user = User(name="Іван Іванов", email="ivan.ivanov@example.com")
# Додаємо його в сесію
db.add(new_user)
# Фіксуємо зміни
db.commit()
# Закриваємо сесію
db.close()
Після виконання цього коду новий запис з'явиться в таблиці users. Зверніть увагу на db.commit() — без нього зміни не збережуться.
Читання записів (Read)
Читання даних у SQLAlchemy — це де починається магія. Ви можете вибирати окремі записи, фільтрувати їх за параметрами або навіть збирати агреговані дані.
- Запит усіх записів
users = db.query(User).all()
for user in users:
print(user.name, user.email)
db.query(User).all() поверне всі записи в таблиці users у вигляді списку.
- Фільтрація даних
Тепер додамо трохи витонченості з фільтрацією. Наприклад, візьмемо користувача з певним email:
user = db.query(User).filter(User.email == "ivan.ivanov@example.com").first()
if user:
print(f"Знайдено користувача: {user.name}")
else:
print("Користувача не знайдено")
Тут ми використали метод .filter() і передали в нього умову. Якщо таких користувачів кілька, використовуйте .all() замість .first().
- Використання операторів
SQLAlchemy підтримує багато операторів для фільтрації. Ось кілька прикладів:
- Рівність:
User.name == "Іван" - Більше/менше:
User.age > 30 - LIKE:
User.name.like("І%") - IN:
User.id.in_([1, 2, 3])
Усі ці оператори можна об'єднувати за допомогою and_, or_ з sqlalchemy:
from sqlalchemy import and_, or_
users = db.query(User).filter(
or_(
User.name == "Іван",
User.email.like("%example.com")
)
).all()
Оновлення записів (Update)
Для оновлення записів використовується комбінація query() і методу update() або оновлення через екземпляр моделі.
Оновлення через екземпляр моделі
user = db.query(User).filter(User.email == "ivan.ivanov@example.com").first()
if user:
user.name = "Іван Петров"
db.commit() # Не забудьте зафіксувати зміни
Просто змінюємо атрибут об'єкта, і після виклику commit() зміни зберігаються в базі даних.
Оновлення через метод update()
Цей спосіб оновлює дані напряму:
db.query(User).filter(User.email == "ivan.ivanov@example.com").update({User.name: "Іван Петров"})
db.commit()
Якщо плануєте оновлювати відразу багато записів, update() працює швидше.
Видалення записів (Delete)
Найбільш драматична з CRUD-операцій — видалення. Щоб видалити запис:
- Знаходимо потрібний об'єкт через
query(). - Викликаємо метод
delete().
Видалення одного запису
user = db.query(User).filter(User.email == "ivan.ivanov@example.com").first()
if user:
db.delete(user)
db.commit()
Видалення відразу кількох записів
db.query(User).filter(User.name.like("І%")).delete()
db.commit()
Майте на увазі, що масове видалення може бути небезпечним. Завжди перевіряйте свої фільтри. Лайфхак для параноїків: спочатку зробіть select() і переконайтеся, що вибираєте тільки потрібні записи.
Обробка помилок при CRUD-операціях
Взаємодія з базою даних не завжди гладка. Можуть траплятися помилки з'єднання, порушення унікальності, відсутні записи і багато іншого. Ось кілька порад, як справлятися з проблемами:
- Використовуйте
try-except
from sqlalchemy.exc import SQLAlchemyError
try:
user = db.query(User).filter(User.id == 1).first()
if user:
db.delete(user)
db.commit()
except SQLAlchemyError as e:
print(f"Виникла помилка: {e}")
db.rollback() # Відкачуємо зміни
- Відкат транзакцій
Якщо щось пішло не так, ви можете відкотити транзакцію за допомогою db.rollback().
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ