Введение SQLAlchemy Core и ORM
SQLAlchemy - это инструментарий базы данных(database toolkit) для Python. Он предоставляет все возможности которые нам нужны при работе с реляционными базами данных , но при этом весь код будет написан на Python. Не нужно писать голые запросы специфичные для каждой реляционной базы данных и при этом задумываться об экранировании и об других важных вещах. Вместо этого SQLAlchemy позволяет абстрагироваться от используемой базы данных. Написанный код на Pyhon будет работать прекрасно работать с разными БД(PostgreSQL, MySQL, SQLite). Если вы на старте проекта используете одну БД , но вам в дальнейшем нужно переключиться на другую, то вы можете это сделать безболезненно и с минимальными усилиями.
SQLAlchemy состоит из двух отдельных компонентов, известных как Core и ORM.
SQLAlchemy Core
Ядро (Core) само по себе является полнофункциональным набором инструментов абстракции SQL, обеспечивающим плавный уровень абстракции для широкого спектра реализаций и вариантов поведения DBAPI, а также языка выражений SQL, который позволяет выражать язык SQL с помощью генеративных выражений Python.
На рисунке выше схематически показано из чего состоит Core, Это схема , типы , язык выражений SQL(SQL Expression Language ) , Engine. Это все поверх DBAPI
На примере рассмотрим , как определить таблицы с использованием Core. Напишем код который подключается к базе данных , создает там необходимые таблицы , добавляет туда нужные данные и извлекает. В качестве базы данных будем использовать SQLite.
Устанавливаем SQLAlchemy
pip install SQLAlchemy
Описание таблиц
from sqlalchemy import MetaData, Table, Column, Integer, String, ForeignKey, Text
metadata_obj = MetaData()
categories = Table('categories', metadata_obj,
Column('id', Integer, primary_key=True),
Column('name', String),
)
posts = Table('posts', metadata_obj,
Column('id', Integer, primary_key=True),
Column('category_id', ForeignKey('categories.id')),
Column('title', String),
Column('content', Text)
)
Код выше описывает две таблицы: categories(Категории) и posts(Посты). Для описания используем Table , который в качестве первого аргумента принимает название таблицы , в качестве второго аргумента экземпляр MetaData, а далее идут сами поля таблиц Column.
Подключение к базе данных и создание таблиц в базе данных.
Полный листинг кода.
from sqlalchemy import create_engine
from sqlalchemy import MetaData, Table, Column, Integer, String, ForeignKey, Text
from sqlalchemy.sql import select
metadata_obj = MetaData()
categories = Table('categories', metadata_obj,
Column('id', Integer, primary_key=True),
Column('name', String),
)
posts = Table('posts', metadata_obj,
Column('id', Integer, primary_key=True),
Column('category_id', ForeignKey('categories.id')),
Column('title', String),
Column('content', Text)
)
if __name__ == '__main__':
engine = create_engine('sqlite:///core_example.db', echo=True)
metadata_obj.create_all(engine)
conn = engine.connect()
insert_category = categories.insert().values(name='Python')
insert_result = conn.execute(insert_category)
last_category_id = insert_result.inserted_primary_key[0]
insert_post = posts.insert().values(title='SqlAlchemy is the best',
category_id=last_category_id,
content='SqlAlchemy text content'
)
conn.execute(insert_post)
for row in conn.execute(select(posts, categories).where(posts.c.category_id == categories.c.id)):
print(row)
В статье Введение FastAPI рассматривается использование SQLALchemy Core.
SQLAlchemy ORM
Хоть SQLAlchemy широко известен своим ORM , но он является опциональным пакетом SQLAlchemy, который построен поверх ядра Core. ORM предоставляет паттерн (data mapper pattern).
Описание таблиц
from sqlalchemy import Column, Integer, String, Text, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Category(Base):
__tablename__ = "categories"
id = Column(Integer, primary_key=True)
name = Column(String)
class Post(Base):
__tablename__ = 'posts'
id = Column(Integer, primary_key=True)
category_id = Column(Integer, ForeignKey('category.id'))
title = Column(String)
content = Column(Text)
Как вы видите для описания таблицы с помощью ORM используется другой подход. Тут таблицы описываются классами , которые наследуются от declarative_base().
В статье SQLAlchemy для новичков рассматривается использование SQLALchemy ORM.
Заключение
В данной статье были рассмотрены SQLAlchemy Core и SQLAlchemy ORM.