Что такое ORM
ORM (Object-Relational Mapping) позволяет работать с базой данных, используя объекты языка программирования вместо SQL-запросов. Python предлагает две основные ORM: Django ORM и SQLAlchemy.
Django ORM: простота и удобство
▸Определение моделей
1from django.db import models23class Category(models.Model):4 name = models.CharField(max_length=100)5 slug = models.SlugField(unique=True)6 created_at = models.DateTimeField(auto_now_add=True)78 class Meta:9 verbose_name_plural = "categories"1011 def __str__(self):12 return self.name1314class Product(models.Model):15 name = models.CharField(max_length=200)16 description = models.TextField(blank=True)17 price = models.DecimalField(max_digits=10, decimal_places=2)18 category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='products')19 is_active = models.BooleanField(default=True)20 created_at = models.DateTimeField(auto_now_add=True)2122 def __str__(self):23 return self.name
▸Запросы
1# Получение всех записей2products = Product.objects.all()34# Фильтрация5active_products = Product.objects.filter(is_active=True)67# Сложные запросы8from django.db.models import Q, F9products = Product.objects.filter(10 Q(category__name='Electronics') & Q(price__lt=100)11)1213# Агрегация14from django.db.models import Avg, Count, Sum15stats = Product.objects.aggregate(16 avg_price=Avg('price'),17 total_count=Count('id'),18 total_value=Sum(F('price') * F('quantity'))19)2021# Асинхронные запросы (Django 4.1+)22async def get_products():23 products = await Product.objects.filter(is_active=True).all()24 return products
▸Миграции
1# Создание миграций2python manage.py makemigrations34# Применение миграций5python manage.py migrate67# Откат миграций8python manage.py migrate myapp 0001
SQLAlchemy: гибкость и мощь
▸Определение моделей
1from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, DateTime2from sqlalchemy.orm import declarative_base, relationship, Session3from datetime import datetime45Base = declarative_base()67class Category(Base):8 __tablename__ = 'categories'910 id = Column(Integer, primary_key=True)11 name = Column(String(100), nullable=False)12 slug = Column(String(100), unique=True, nullable=False)13 created_at = Column(DateTime, default=datetime.utcnow)1415 products = relationship("Product", back_populates="category")1617class Product(Base):18 __tablename__ = 'products'1920 id = Column(Integer, primary_key=True)21 name = Column(String(200), nullable=False)22 description = Column(String, default='')23 price = Column(Integer, nullable=False) # Храним в копейках24 category_id = Column(Integer, ForeignKey('categories.id'))2526 category = relationship("Category", back_populates="products")
▸Запросы
1from sqlalchemy import select, func, and_, or_2from sqlalchemy.orm import selectinload34# Простой запрос5stmt = select(Product).where(Product.is_active == True)6products = session.execute(stmt).scalars().all()78# Сложные запросы9stmt = (10 select(Product)11 .options(selectinload(Product.category)) # Eager loading12 .where(13 and_(14 Product.category.has(name='Electronics'),15 Product.price < 10000 # 100 рублей в копейках16 )17 )18 .order_by(Product.price.desc())19 .limit(10)20)2122# Агрегация23stmt = (24 select(25 Product.category_id,26 func.count(Product.id).label('count'),27 func.avg(Product.price).label('avg_price')28 )29 .group_by(Product.category_id)30 .having(func.count(Product.id) > 5)31)
▸Асинхронный SQLAlchemy
1from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession2from sqlalchemy.orm import sessionmaker34engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/db")5async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)67async def get_products():8 async with async_session() as session:9 result = await session.execute(10 select(Product).where(Product.is_active == True)11 )12 return result.scalars().all()
Сравнение
▸Производительность
▸Миграции
▸Типизация
▸Асинхронность
Когда что использовать
▸Django ORM
▸SQLAlchemy
Заключение
Django ORM и SQLAlchemy — обе мощные ORM, каждая со своими преимуществами. Django ORM проще для начала, SQLAlchemy предоставляет больше возможностей и гибкости. Выбор зависит от фреймворка и требований проекта.