Модели представляют классы, которые соответствуют определению таблиц в базе данных и объекты которых хранятся в этих таблицах. И одним из преимуществ SQLAlchemy является то, что мы можем работать таблицами через эти модели-классы языка Python, не прибегая к созданию запросов на языке SQL. А SQLAlchemy сама сможет сопоставить классы с таблицами, а атрибуты - со столбцами в таблице.
Для создания моделей необходима базовая модель, от которой потом наследуются остальные модели. Начиная с версии SQLAlchemy 2.0 для создания базовой модели надо создать класс, унаследованный от DeclarativeBase:
from sqlalchemy.orm import DeclarativeBase class Base(DeclarativeBase): pass
То есть в данном случае определяется класс Base - базовая модель.
Стоит отметить, что приложениях до версии SQLAlchemy 2.0 можно встретить другой способ - применение функции declarative_base()
:
from sqlalchemy.ext.declarative import declarative_base Base = declarative_base()
Этот способ начиная с версии SQLAlchemy 2.0 объявлен устаревшим.
Классы, которые наследуются от класса базовой модели, будут сопоставляться с таблицами в базе данных. Для сопоставления класса с определенной таблицей в БД применяется
атрибут класса __tablename__. Например, определим модель Person
from sqlalchemy.orm import DeclarativeBase from sqlalchemy import Column, Integer, String class Base(DeclarativeBase): pass class Person(Base): __tablename__ = "people" id = Column(Integer, primary_key=True, index=True) name = Column(String) age = Column(Integer)
Итак, класс Person наследуется от базой модели Base и проецируется на таблицу "people". То есть объекты класса Person будут храниться в таблице "people".
Для хранения данных в классе модели определяются атрибуты, которые сопоставляются со столбцами таблицы. В данном случае класс Person определяет три таких атрибута: id, name и age, для которых в таблице people будут создаваться одноименные столбцы.
Для опреления атрибутов-столбцов есть разные способы. Стандартный способ представляет создание для каждого атрибута-столбца объекта Column.
Класс Column с помощью параметров конструктора определяет настройки столбца в таблицы. Здесь в конструктор вначале передается тип столбца. Так, у id и age тип столбца -
Integer
, то есть целое число. А столбец name представляет тип String
, то есть строку.
Кроме того, в конструктор можно передать ряд дополнительных параметров. Так, для столбца id передаются параметры primary_key
и index
.
Значение primary_key=True
указывает, что данный столбец будет представлять первичный ключ. А параметр index=True
говорит, что для данного столбца будет создаваться индекс. Стоит отметить, что один из атрибутов-столбцов модели должен представлять первичный ключ, как в примере выше атрибут id.
Для определения столбца для класса Column можно установить ряд параметров. Отметим основные:
name
: имя столбца. Названия в нижнем регистре считаются регистронезависимыми. Если параметр опущен, то по умолчанию используются названия атрибутов. Это первый позиционный аргумент
type_
: тип данных столбца, который задается в виде объекта подкласса TypeEngine. Это второй позиционный аргумент
autoincrement
: задает автоинкремент значения столбца. Может иметь значения True, False, auto. Значение auto
- значение по умолчанию, которое говорит, что стобец
первичного ключа с типом INTEGER будет автоматически увеличивать свое значение при добавлении нового объекта в таблицу. Данный параметр применяется только для столбцов с типами
INT, SMALLINT, BIGINT.
default
: устанавливает значение по умолчанию
index
: если равен True
, то для столбца будет создаваться индекс
nullable
: если равен False
, то к определению столбца в бд будет добавляться
ограничение NOT NULL
. Для всех столбцов, кроме столбца первичного ключа, значение по умолчанию - True
primary_key
: если равен True
, то столбец будет считаться первичным ключом
unique
: если равен True
, то для столбца будет создаваться ограничение UNIQUE
, благодаря чему столбец будет поддерживать только уникальные значения
В качестве типов для столбцов можно использовать один из следующих встроенных типов:
BigInteger
: целые числа
Boolean
: булевый тип
Date
: объект datetime.date()
DateTime
: объект datetime.datetime()
Enum
: тип Enum
Float
: тип для чисел с плавающей точкой, например, FLOAT
и REAL
.
Integer
: целые числа
Interval
: объект datetime.timedelta()
LargeBinary
: большие наборы байтов
MatchType
: соответствует результату оператора MATCH.
Numeric
: базовый тип для дробных числовых данных, например, NUMERIC
, FLOAT
, DECIMAL
.
PickleType
: для объектов Python, которые сериализованы с помощью модуля pickle.
SmallInteger
: целые числа
String
: строки
Text
: строки произвольной длины.
Time
: объект datetime.time()
Unicode
: строка символов Unicode произвольной длины.
UnicodeText
: строка Unicode неограниченной длины.
Для создания базы данных и таблиц по метаданным моделей применяется метод Base.metadata.create_all(). Его ключевой параметр - bind принимает класс, который используется для подключения к базе данных. В качестве такого класса применяется созданный ранее движок SQLAlchemy. Если база данных и все необходимые таблицы уже имеются, то метод не создает заново таблицы.
Например, создадим таблицу people по выше определенной модели Person:
from sqlalchemy import create_engine from sqlalchemy import Column, Integer, String from sqlalchemy.orm import DeclarativeBase # строка подключения sqlite_database = "sqlite:///metanit.db" # создаем движок SqlAlchemy engine = create_engine(sqlite_database) #создаем базовый класс для моделей class Base(DeclarativeBase): pass # создаем модель, объекты которой будут храниться в бд class Person(Base): __tablename__ = "people" id = Column(Integer, primary_key=True, index=True) name = Column(String) age = Column(Integer,) # создаем таблицы Base.metadata.create_all(bind=engine) print("База данных и таблица созданы")
В итоге в текущей папке будет создана база данных metanit.db с таблицей people. И мы можем открыть эту базу данных с помощью любой программы для просмотра баз данных sqlite (например, с помощью DB Browser for SQLite) и увидеть содержимое бд: