Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Miron-Anosov/a4741ad86f19124dc6f86e3a5e58c61e to your computer and use it in GitHub Desktop.
Save Miron-Anosov/a4741ad86f19124dc6f86e3a5e58c61e to your computer and use it in GitHub Desktop.

Руководство по Events в SQLAlchemy

Теоретическое введение

Events (события) в SQLAlchemy - это мощный механизм прослушивания и перехвата различных операций, происходящих в ORM. Они позволяют разработчикам внедрять пользовательскую логику в различные стадии жизненного цикла объектов и запросов.

Основные концепции

Events можно разделить на несколько основных категорий:

  • Mapper Events: События, связанные с отображением моделей
  • Instance Events: События, происходящие с конкретными экземплярами моделей
  • Query Events: События, связанные с выполнением запросов
  • Session Events: События, происходящие в сессии SQLAlchemy

Синтаксис и примеры событий

1. Базовый синтаксис регистрации событий

from sqlalchemy import event
from sqlalchemy.orm import Session

# Регистрация события
@event.listens_for(SomeModel, 'before_insert')
def receive_before_insert(mapper, connection, target):
    # Пользовательская логика перед вставкой
    pass

2. Основные типы событий

Mapper Events

# Событие перед загрузкой объекта
@event.listens_for(User, 'load')
def receive_load(target, context):
    # Логика после загрузки объекта
    pass

# Событие перед инициализацией
@event.listens_for(User, 'init')
def receive_init(target, args, kwargs):
    # Логика при создании объекта
    pass

Session Events

# Событие перед фиксацией транзакции
@event.listens_for(session, 'before_commit')
def receive_before_commit(session):
    # Проверка или модификация данных перед коммитом
    pass

# Событие после фиксации
@event.listens_for(session, 'after_commit')
def receive_after_commit(session):
    # Действия после успешного коммита
    pass

Instance Events

# Событие перед вставкой
@event.listens_for(User, 'before_insert')
def receive_before_insert(mapper, connection, target):
    # Автоматическое заполнение полей
    target.created_at = datetime.now()

# Событие после обновления
@event.listens_for(User, 'after_update')
def receive_after_update(mapper, connection, target):
    # Логирование изменений
    log_model_changes(target)

3. Продвинутые техники

Условные события

@event.listens_for(User, 'before_insert', propagate=True)
def receive_before_insert(mapper, connection, target):
    # Событие только для определенных условий
    if target.is_active:
        # Специфическая логика
        pass

Декоратор с параметрами

def log_event(func):
    @event.listens_for(User, 'after_insert')
    def wrapper(mapper, connection, target):
        print(f"Logging: {func.__name__}")
        return func(mapper, connection, target)
    return wrapper

Интеграция с Flask и FastAPI

Flask Example

from flask import Flask
from sqlalchemy import event
from models import User

app = Flask(__name__)
db = SQLAlchemy(app)

@event.listens_for(User, 'after_insert')
def user_created_notification(mapper, connection, target):
    # Отправка уведомления после создания пользователя
    send_welcome_email(target)

FastAPI Example

from fastapi import FastAPI
from sqlalchemy import event
from models import User

app = FastAPI()

@event.listens_for(User, 'before_update')
def validate_user_update(mapper, connection, target):
    # Дополнительная валидация перед обновлением
    validate_user_changes(target)

Лучшие практики и антипаттерны

Рекомендации

  • Используйте события для кроссфункциональной логики
  • Держите события легковесными и быстрыми
  • Используйте для валидации, логирования, нотификаций
  • Применяйте с осторожностью для сложных бизнес-процессов

Антипаттерны

  • Не усложняйте бизнес-логику событиями
  • Избегайте тяжелых вычислений в обработчиках событий
  • Не используйте для основной бизнес-логики
  • Не создавайте слишком сложные зависимости между событиями

Когда использовать

✅ Аудит и логирование ✅ Автоматическое заполнение полей ✅ Отправка уведомлений ✅ Валидация данных ✅ Кэширование

Когда избегать

❌ Сложная бизнес-логика ❌ Тяжелые вычисления ❌ Асинхронные операции ❌ Сложные транзакции

Заключение

Events в SQLAlchemy - мощный инструмент для расширения функциональности ORM, но требуют аккуратного и продуманного применения.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment