← Назад к вопросам

Какие знаешь два основных компонента в SQLAlchemy?

2.3 Middle🔥 251 комментариев
#Базы данных (SQL)

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Два основных компонента в SQLAlchemy

SQLAlchemy — это мощный ORM (Object-Relational Mapping) фреймворк для Python. Она состоит из двух основных компонентов, которые работают на разных уровнях абстракции.

1. Core (Ядро) — SQL Expression Language

SQL Expression Language — это низкоуровневый компонент, который работает непосредственно с SQL.

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, select

# Создание таблицы через Core
metadata = MetaData()
users_table = Table(
    'users',
    metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String(50)),
    Column('email', String(100), unique=True)
)

# Создание двигателя и подключения
engine = create_engine('postgresql://user:password@localhost/dbname')

# SQL SELECT через Core
stmt = select(users_table).where(users_table.c.id == 1)

with engine.connect() as conn:
    result = conn.execute(stmt)
    for row in result:
        print(row)

Преимущества Core:

  • Полный контроль над SQL
  • Не требует определения классов
  • Работает с любым подходом
  • Строит SQL программно

Использование Core для различных операций:

from sqlalchemy import select, insert, update, delete

# INSERT
stmt = insert(users_table).values(name='John', email='john@example.com')
result = conn.execute(stmt)

# UPDATE
stmt = update(users_table).where(users_table.c.id == 1).values(name='Jane')
result = conn.execute(stmt)

# DELETE
stmt = delete(users_table).where(users_table.c.id == 1)
result = conn.execute(stmt)

# SELECT с условиями и JOIN
from sqlalchemy import and_, or_

stmt = select(users_table).where(
    and_(
        users_table.c.name.like('J%'),
        users_table.c.email != None
    )
)

# JOIN
posts_table = Table('posts', metadata, Column('id', Integer, primary_key=True), ...)
stmt = select(users_table, posts_table).join(
    posts_table,
    users_table.c.id == posts_table.c.user_id
)

2. ORM (Object-Relational Mapping) — Declarative

ORM компонент позволяет работать с таблицами как с Python классами.

from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import declarative_base, relationship, Session

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    
    id: int = Column(Integer, primary_key=True)
    name: str = Column(String(50), nullable=False)
    email: str = Column(String(100), unique=True, nullable=False)
    posts = relationship('Post', back_populates='author')
    
    def __repr__(self):
        return f'<User(id={self.id}, name={self.name}, email={self.email})>'

class Post(Base):
    __tablename__ = 'posts'
    
    id: int = Column(Integer, primary_key=True)
    title: str = Column(String(200), nullable=False)
    content: str = Column(String, nullable=False)
    user_id: int = Column(Integer, ForeignKey('users.id'), nullable=False)
    author = relationship('User', back_populates='posts')
    
    def __repr__(self):
        return f'<Post(id={self.id}, title={self.title})>'

# Создание таблиц
engine = create_engine('postgresql://user:password@localhost/dbname')
Base.metadata.create_all(engine)

# Работа с ORM
with Session(engine) as session:
    # CREATE
    user = User(name='John', email='john@example.com')
    session.add(user)
    session.commit()
    
    # READ
    john = session.query(User).filter_by(name='John').first()
    print(john)  # <User(id=1, name=John, email=john@example.com)>
    
    # UPDATE
    john.email = 'newemail@example.com'
    session.commit()
    
    # DELETE
    session.delete(john)
    session.commit()
    
    # Relationships
    user = session.query(User).filter_by(id=1).first()
    for post in user.posts:  # Автоматическая загрузка связанных постов
        print(post.title)

Сравнение Core и ORM

АспектCoreORM
АбстракцияНизкаяВысокая
Контроль над SQLПолныйМеньше
Скорость разработкиМедленнееБыстрее
ПроизводительностьБыстрееНемного медленнее
СложностьПрощеСложнее
Идеально дляСложные запросыСтандартные операции

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

# Сложные запросы с множественными JOIN и условиями
from sqlalchemy import and_, or_, func

query = select(
    users_table.c.id,
    users_table.c.name,
    func.count(posts_table.c.id).label('post_count')
).join(
    posts_table,
    users_table.c.id == posts_table.c.user_id
).where(
    and_(
        users_table.c.created_at > '2024-01-01',
        or_(
            posts_table.c.views > 100,
            posts_table.c.likes > 50
        )
    )
).group_by(users_table.c.id)

# Этот запрос проще писать в Core чем в ORM
with engine.connect() as conn:
    result = conn.execute(query)

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

# Простые CRUD операции
with Session(engine) as session:
    # Создание
    user = User(name='Alice', email='alice@example.com')
    session.add(user)
    session.commit()
    
    # Чтение
    users = session.query(User).all()
    
    # Обновление
    user.name = 'Alicia'
    session.commit()
    
    # Удаление
    session.delete(user)
    session.commit()

# ORM с relationships — очень удобно
user = session.query(User).filter_by(id=1).first()
for post in user.posts:  # Автоматически загружает related objects
    print(post.title)

Гибридный подход

Вы можете использовать оба компонента вместе:

from sqlalchemy import text

# Используем ORM для простых операций
user = session.query(User).filter_by(id=1).first()

# Используем raw SQL для сложного запроса
result = session.execute(
    text('SELECT * FROM users WHERE created_at > :date'),
    {'date': '2024-01-01'}
)

# Используем Core для сложного запроса
from sqlalchemy import select, func, desc

query = select(
    User.id,
    User.name,
    func.count(Post.id).label('post_count')
).join(Post).group_by(User.id).order_by(desc('post_count'))

results = session.execute(query).fetchall()

SQLAlchemy 2.0 - новый стиль

from sqlalchemy import create_engine, select
from sqlalchemy.orm import declarative_base, Session

engine = create_engine('postgresql://...')
Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id: int = Column(Integer, primary_key=True)
    name: str = Column(String)

# SQLAlchemy 2.0 рекомендует этот стиль
with Session(engine) as session:
    # Используй select() вместо query()
    stmt = select(User).where(User.id == 1)
    user = session.scalars(stmt).first()
    print(user)

Выводы

Два основных компонента SQLAlchemy:

  1. Core (SQL Expression Language) — низкоуровневый, полный контроль над SQL

    • Используй для сложных запросов
    • Лучше для performance-critical кода
    • Работает без определения классов
  2. ORM (Object-Relational Mapping) — высокоуровневый, работаешь с классами Python

    • Используй для стандартных CRUD операций
    • Лучше для быстрой разработки
    • Отлично работает с relationships

Best Practice:

  • Начни с ORM для простоты
  • Переходи на Core когда нужны сложные запросы
  • Комбинируй оба подхода в большом проекте
  • В SQLAlchemy 2.0 используй select() вместо query()

Знание обоих компонентов делает тебя гибким разработчиком, способным решать задачи на оптимальном уровне абстракции.