AI Notes
January 19

ORM методы

Использование ORM-методов в SQLAlchemy предполагает работу с объектами классов (моделей), которые представляют строки таблиц базы данных. Вместо написания SQL-запросов вы работаете с объектами, их атрибутами и методами. Это делает код более читаемым и легко поддерживаемым.

Основные этапы работы с ORM-методами

1. Создание и настройка модели

Определите модели, которые будут соответствовать таблицам в базе данных. Пример:

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class User(Base):
    __tablename__ = "users"
    
    id = Column(Integer, primary_key=True)
    username = Column(String, nullable=False)
    email = Column(String, unique=True)

2. Добавление записей

Вы создаёте экземпляры классов, заполняете их атрибуты и добавляете в сессию:

async with async_session() as session:
    new_user = User(username="JohnDoe", email="john@example.com")
    session.add(new_user)
    await session.commit()

3. Чтение записей

Для получения данных вы используете запросы через session.query или session.get:

async with async_session() as session:
    user = await session.get(User, 1)  # Получение пользователя по первичному ключу
    if user:
        print(user.username, user.email)

4. Обновление записей

Для обновления записей достаточно изменить атрибуты объекта и вызвать session.commit:

async with async_session() as session:
    user = await session.get(User, 1)  # Находим объект
    if user:
        user.email = "new_email@example.com"  # Изменяем атрибут
        await session.commit()  # Сохраняем изменения

5. Удаление записей

Для удаления записей используется метод session.delete:

async with async_session() as session:
    user = await session.get(User, 1)  # Находим объект
    if user:
        await session.delete(user)  # Удаляем объект
        await session.commit()  # Сохраняем изменения

Преимущества использования ORM-методов

  • Скрытие SQL-запросов: Нет необходимости вручную писать SQL-код.
  • Интуитивность: Вы работаете с объектами Python, что делает код естественным.
  • Связи между таблицами: ORM позволяет легко работать с отношениями, например, one-to-many или many-to-many.

Пример сложной операции

Допустим, у вас есть пользователь, у которого может быть несколько постов. Нужно добавить новый пост для пользователя:

class Post(Base):
    __tablename__ = "posts"

    id = Column(Integer, primary_key=True)
    title = Column(String, nullable=False)
    content = Column(String, nullable=False)
    user_id = Column(Integer, ForeignKey("users.id"), nullable=False)

    user = relationship("User", back_populates="posts")

class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True)
    username = Column(String, nullable=False)
    posts = relationship("Post", back_populates="user")

Добавим пост:

async with async_session() as session:
    user = await session.get(User, 1)
    if user:
        new_post = Post(title="My First Post", content="Hello, world!", user_id=user.id)
        user.posts.append(new_post)  # Можно работать через `relationship`
        await session.commit()

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

  1. Работайте через relationship Используйте связи между таблицами (например, user.posts) для упрощения кода.
  2. Используйте сессии аккуратно Каждый запрос должен выполняться в пределах асинхронной сессии (async with async_session()).
  3. Оптимизируйте запросы Если нужно загрузить связанные данные, используйте joinedload или selectinload:
from sqlalchemy.orm import joinedload

async with async_session() as session:
    user = await session.execute(
        select(User).options(joinedload(User.posts)).where(User.id == 1)
    )
    user = user.scalar_one_or_none()