SQLAlchemy vs Django ORM: що вибрати для роботи з базою даних у Python веб-застосунках
Насправді вибір «правильного» ORM для конкретного застосунка є надзвичайно важливим кроком, не менш важливим, ніж вибір відповідної бази даних для вашого веб-застосунка.
Чому потрібен ORM?
Перш за все це автоматична генерація запитів (не пишете «сирі» SQL-запити, а працюєте з Python-об’єктами).
Також захист від SQL-ін’єкцій (сирі SQL-запити — вразливі).
Єдиний синтаксис для різних СУБД зменшує необхідність оновлення запитів при зміні СУБД).
Наступне завдання ORM автоматичне створення міграцій і управління ними.
Зменшення кількості повторюваного коду (створіть модель та використовуйте її).
Підтримка статичної типізації в Python.
Звичайно, ORM мають свої недоліки. У більшості випадків це стосується продуктивності запитів і додаткового споживання пам’яті веб-сервером. Проте зазвичай розробники віддають перевагу підтримуваності коду та його гнучкості, ніж передчасній оптимізації.
Головні відмінності SQLAlchemy та Django ORM
1. Опис моделей
Опис моделей є простим і лаконічним в обох ORM.
Django ORM
from django.db import models class Person(models.Model): name = models.CharField(max_length=100) age = models.IntegerField()
SQLAlchemy
from sqlalchemy import Column, Integer, String from sqlalchemy.orm import declarative_base Base = declarative_base() class Person(Base): __tablename__ = 'persons’' id = Column(Integer, primary_key=True) name = Column(String(100)) age = Column(Integer)
2. Обробка запитів
Прості запити
Обидві ORM добре справляються з простими запитами.
Django ORM
from django.db.models import Avg avg_age = Person.objects.aggregate(Avg('age'))
SQLAlchemy
from sqlalchemy.sql import func avg_age = session.query(func.avg(Person.age)).scalar()
3. Складні запити
Обидві ORM добре справляються зі складними запитами. На проілюстрованому прикладі ми бачимо як вкладені запити з агрегаціями достатньо просто описуються і потім генеруються в 1 SQL запит.
SQLAlchemy (з підзапитом)
# Підзапит: обчислення середнього віку персон, згрупованих за першою літерою імені avg_age_subquery = ( select( func.left(Person.name, 1).label("first_letter"), func.avg(Person.age).label("avg_age") ) .group_by(func.left(Person.name, 1)) .subquery() ) avg_alias = aliased(avg_age_subquery) # Основний запит: вибір персон, які старші за середній вік у своїй групі complex_query = ( session.query(Person) .join(avg_alias, func.left(Person.name, 1) == avg_alias.c.first_letter) .filter(Person.age > avg_alias.c.avg_age) )
Django ORM (з підзапитом)
avg_age_subquery = ( Person.objects .annotate(first_letter=Substr('name', 1, 1)) # Перша буква імені .values('first_letter') .annotate(avg_age=Avg('age')) # Середній вік для кожної букви .values('first_letter', 'avg_age') # Залишаємо тільки необхідні поля ) # Основний запит: вибір користувачів, які старші за середній вік у своїй групі complex_query = ( Person.objects .annotate(first_letter=Substr('name', 1, 1)) .filter( age__gt=Subquery(avg_age_subquery.filter(first_letter=OuterRef('first_letter')).values('avg_age')[:1]) ) )
4. Міграції
Django ORM має вбудовану систему міграцій, підтримує автоматичне генерування змін схеми бази даних.
SQLAlchemy не має вбудованої системи міграцій, потрібно використовувати Alembic для управління ними.
5. Обробка великих наборів даних
Обидві ORM підтримують вигрузку батчами.
Django ORM
for person in Person.objects.iterator(): print(person.name)
SQLAlchemy
for person in session.query(Person).yield_per(1000): print(person.name)
Порівняльна таблиця
Функціональність |
Django ORM |
SQLAlchemy |
Простота використання |
Так |
Вимагає додаткових конфігурацій |
Оптимізація складних запитів |
Повний контроль |
Повний контроль |
Міграції |
Вбудовані |
Потрібен Alembic |
Обробка великої кількості даних батчами |
Повна підтримка |
Повна підтримка |
Висновки
Django ORM підходить, якщо:
- Ви працюєте з Django-проектом.
- Швидка розробка без зайвих налаштувань.
SQLAlchemy є кращим вибором, якщо:
- Ви розробляєте мікросервіс і не хочете використовувати всю екосистему Django.
- Завдяки додатковим конфігураціям хочете мати більше контролю для роботи з БД.
Загалом, як бачите порівняння, то немає великої різниці між цими двома ORM. Обидва інструменти дуже потужні і будуть у нагоді в будь-якому проекті. Django буде легше для початківців, бо має більш простіший інтерфейс для використання. Але не потрібно поспішати і робити висновок, що з її допомогою розробляються лише прості проекти. Я зустрічав достатньо складні проекти, які розроблені на Django і за продуктивністю вони не поступались проектам на SQLAlchemy.
SQLAlchemy у свою чергу вам дасть більше гнучкості у роботі з іншими бібліотеками, вам не потрібно буде використовувати екосистему Django (тільки якщо ви сильно захочете). Більша конфігурованість може стати в нагоді, якщо потріно буде робити додаткові оптимізації. Із мінусів, більший поріг входу, бо потрібно буде конфігурувати деякі речі в ORM самому. Додатково потрібно буде встановлювати Alembic для міграцій і розбиратись ще із ним.
Краще обирайте той інструмент, яким команда володіє краще і тоді розробка буде швидка і спокійна. 🙂
6 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів