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

SQLAlchemy Core основан на концепции SQL выражений, которые позволяют строить и выполнять SQL-запросы в стиле Python. Это делает код более читаемым и поддерживаемым, особенно при работе с сложными запросами. Кроме того, SQLAlchemy Core абстрагирует взаимодействие с различными системами управления базами данных (СУБД), что позволяет легко переключаться между ними, не меняя основной код приложения.

Создание моделей

SQLAlchemy Core использует декларативный стиль для определения схемы базы данных, что позволяет явно указывать структуру таблиц и их столбцов. В отличие от SQLAlchemy ORM, где таблицы и столбцы определяются через классы и атрибуты, в Core все делается с помощью объектов и функций, предоставляемых библиотекой.

Этот подход обеспечивает больше гибкости и контроля над структурой базы данных, что особенно полезно в случаях, когда требуется реализовать сложные схемы или специфичные для СУБД функции.

Пример создания таблицы

В SQLAlchemy Core создание моделей начинается с определения метаданных и таблиц. Метаданные (MetaData) представляют собой контейнер для всех объектов базы данных (таблиц, индексов и т.д.), и используются для упрощения управления ими.

Давайте рассмотрим, как создать таблицу users, которая будет содержать информацию о пользователях, включая их идентификатор, имя и возраст.

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

# Создание подключения к базе данных SQLite
engine = create_engine('sqlite:///example.db')

# Определение метаданных
metadata = MetaData()

# Определение таблицы users
users = Table('users', metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String, nullable=False),
    Column('age', Integer)
)

# Создание таблицы в базе данных
metadata.create_all(engine)

В этом примере мы создали таблицу users с тремя столбцами: id, name и age. Столбец id является первичным ключом, столбец name имеет ограничение NOT NULL, а столбец age может содержать NULL значения.

Metadata (Метаданные) в SQLAlchemy — это объект, который служит контейнером для всей схемы базы данных. Он хранит информацию о таблицах, столбцах, связях между таблицами и других аспектах структуры базы данных. Метаданные позволяют управлять этой информацией централизованно и предоставляют удобные методы для создания, изменения и удаления схемы базы данных.

Определение столбцов и их типов

SQLAlchemy Core поддерживает множество типов данных, которые могут быть использованы для определения столбцов. Вот некоторые из них:

  • Integer — целочисленные значения
  • String — строковые значения
  • Boolean — логические значения
  • DateTime — дата и время
  • Float — числа с плавающей точкой

Пример использования различных типов данных:

from sqlalchemy import DateTime, Boolean, Float

# Определение таблицы с различными типами данных
items = Table('items', metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String, nullable=False),
    Column('price', Float, nullable=False),
    Column('in_stock', Boolean, default=True),
    Column('created_at', DateTime)
)

Определение внешних ключей

Внешние ключи устанавливают связи между таблицами.

Пример определения первичных и внешних ключей:

from sqlalchemy import ForeignKey

# Определение таблицы orders с внешним ключом
orders = Table('orders', metadata,
    Column('id', Integer, primary_key=True),
    Column('user_id', Integer, ForeignKey('users.id')),
    Column('item_id', Integer, ForeignKey('items.id')),
    Column('quantity', Integer, nullable=False)
)

В этом примере таблица orders содержит два внешних ключа: user_id и item_id, которые ссылаются на таблицы users и items соответственно.

Основные операции с данными

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

Вставка данных

Вставка данных в таблицу выполняется с помощью объекта insert(). Существует несколько способов вставки данных: вставка одной строки, массовая вставка нескольких строк, а также использование транзакций для обеспечения целостности данных.

Вставка одной строки

Для вставки одной строки используем метод insert().values():

from sqlalchemy import insert

# Вставка одной строки в таблицу users
insert_stmt = insert(users).values(name='John Doe', age=30)
conn = engine.connect()
conn.execute(insert_stmt)
conn.close()

В этом примере мы создаем SQL-запрос для вставки новой записи в таблицу users и выполняем его с помощью соединения.

Массовая вставка данных

Массовая вставка данных позволяет вставлять сразу несколько строк за один запрос, что значительно ускоряет процесс:

# Массовая вставка данных в таблицу users
mass_insert_stmt = users.insert().values([
    {'name': 'Jane Doe', 'age': 25},
    {'name': 'Mike Smith', 'age': 40}
])
conn = engine.connect()
conn.execute(mass_insert_stmt)
conn.close()

В этом примере мы используем список словарей для вставки нескольких записей в таблицу users.

Чтение данных

Чтение данных из таблицы выполняется с помощью объекта select(). Мы можем выполнять простые SELECT-запросы, а также использовать фильтры и условия для выборки данных.

Простые SELECT-запросы

Простой SELECT-запрос выбирает все строки из таблицы:

from sqlalchemy import select

# SELECT-запрос для выборки всех данных из таблицы users
select_stmt = select([users])
conn = engine.connect()
result = conn.execute(select_stmt)
for row in result:
    print(row)
conn.close()

В этом примере мы выбираем все записи из таблицы users и выводим их на экран.

Использование фильтров и условий

Мы можем использовать метод where() для добавления условий в запрос:

# SELECT-запрос с условием
select_stmt = select([users]).where(users.c.age > 30)
conn = engine.connect()
result = conn.execute(select_stmt)
for row in result:
    print(row)
conn.close()

Этот запрос выбирает всех пользователей старше 30 лет.

Обновление данных

Обновление данных выполняется с помощью объекта update(), который позволяет изменять значения столбцов по заданным условиям.

from sqlalchemy import update

# Обновление данных в таблице users
update_stmt = update(users).where(users.c.name == 'John Doe').values(age=31)
conn = engine.connect()
conn.execute(update_stmt)
conn.close()

В этом примере мы обновляем возраст пользователя с именем John Doe.

Удаление данных

Удаление данных выполняется с помощью объекта delete(), который позволяет удалять строки по заданным условиям.

from sqlalchemy import delete

# Удаление данных из таблицы users
delete_stmt = delete(users).where(users.c.name == 'Jane Doe')
conn = engine.connect()
conn.execute(delete_stmt)
conn.close()

В этом примере мы удаляем пользователя с именем Jane Doe.

Работа с транзакциями

Для обеспечения целостности данных и защиты от ошибок, связанных с выполнением нескольких операций, мы можем использовать транзакции. Транзакции позволяют объединить несколько операций в одно целое, что гарантирует, что либо все операции будут выполнены успешно, либо ни одна из них не будет применена.

from sqlalchemy import exc

try:
    with engine.begin() as conn:
        conn.execute(users.insert().values(name='Alice', age=22))
        conn.execute(users.insert().values(name='Bob', age=23))
except exc.SQLAlchemyError:
    print("Ошибка при выполнении транзакции")

В этом примере мы используем контекстный менеджер для управления транзакцией. Если одна из операций завершится ошибкой, транзакция будет отменена, и ни одна из вставок не будет выполнена.