Сохранение данных Python - SQLAlchemy

Любая реляционная база данных хранит данные в виде таблиц. Структура таблицы определяет тип данных атрибутов, которые в основном представляют собой только первичные типы данных, которые сопоставляются с соответствующими встроенными типами данных Python. Однако определяемые пользователем объекты Python не могут постоянно храниться и извлекаться в / из таблиц SQL.

Это несоответствие между типами SQL и объектно-ориентированными языками программирования, такими как Python. SQL не имеет эквивалентного типа данных для других типов данных, таких как dict, tuple, list или любого определенного пользователем класса.

Если вам необходимо сохранить объект в реляционной базе данных, перед выполнением запроса INSERT необходимо сначала деконструировать его атрибуты экземпляра в типы данных SQL. С другой стороны, данные, полученные из таблицы SQL, относятся к первичным типам. Объект Python желаемого типа должен быть создан с использованием для использования в скрипте Python. Вот где пригодятся объектно-реляционные сопоставители.

Сопоставитель отношений объектов (ORM)

An Object Relation Mapper(ORM) - это интерфейс между классом и таблицей SQL. Класс Python сопоставляется с определенной таблицей в базе данных, поэтому преобразование между объектами и типами SQL выполняется автоматически.

Класс "Студенты", написанный на языке Python, отображается в таблице "Студенты" в базе данных. В результате все операции CRUD выполняются путем вызова соответствующих методов класса. Это избавляет от необходимости выполнять жестко запрограммированные SQL-запросы в скрипте Python.

Таким образом, библиотека ORM действует как слой абстракции над необработанными SQL-запросами и может помочь в быстрой разработке приложений. SQLAlchemy- популярный объектно-реляционный картограф для Python. Любые манипуляции с состоянием объекта модели синхронизируются с соответствующей строкой в ​​таблице базы данных.

Библиотека SQLALchemy включает ORM API и язык выражений SQL (SQLAlchemy Core). Язык выражений напрямую выполняет примитивные конструкции реляционной базы данных.

ORM - это высокоуровневый и абстрактный шаблон использования, созданный на основе языка выражений SQL. Можно сказать, что ORM - это прикладное использование языка выражений. В этой теме мы обсудим SQLAlchemy ORM API и будем использовать базу данных SQLite.

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

  • Firebird
  • Microsoft SQL Server
  • MySQL
  • Oracle
  • PostgreSQL
  • SQLite
  • Sybase

Установка SQLAlchemy проста и понятна с помощью утилиты pip.

pip install sqlalchemy

Чтобы проверить, правильно ли установлена ​​SQLalchemy и ее версия, введите в командной строке Python следующее:

>>> import sqlalchemy
>>>sqlalchemy.__version__
'1.3.11'

Взаимодействие с базой данных осуществляется через объект Engine, полученный как возвращаемое значение create_engine() функция.

engine =create_engine('sqlite:///mydb.sqlite')

SQLite позволяет создавать базу данных в памяти. Механизм SQLAlchemy для базы данных в памяти создается следующим образом:

from sqlalchemy import create_engine
engine=create_engine('sqlite:///:memory:')

Если вы собираетесь использовать базу данных MySQL, используйте ее модуль DB-API - pymysql и соответствующий драйвер диалекта.

engine = create_engine('mysql+pymydsql://root@localhost/mydb')

Create_engine имеет необязательный аргумент эха. Если установлено значение true, запросы SQL, сгенерированные движком, будут отображаться на терминале.

SQLAlchemy содержит declarative baseкласс. Он действует как каталог классов моделей и сопоставленных таблиц.

from sqlalchemy.ext.declarative import declarative_base
base=declarative_base()

Следующим шагом является определение класса модели. Он должен быть производным от базового объекта класса declarative_base, как указано выше.

Набор __tablename__ для имени таблицы, которую вы хотите создать в базе данных. Остальные атрибуты соответствуют полям. Каждый из них является объектом столбца в SQLAlchemy, а его тип данных - из одного из списка ниже -

  • BigInteger
  • Boolean
  • Date
  • DateTime
  • Float
  • Integer
  • Numeric
  • SmallInteger
  • String
  • Text
  • Time

Следующий код - это класс модели с именем Student, который сопоставлен с таблицей Student.

#myclasses.py
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Numeric
base=declarative_base()
class Student(base):
   __tablename__='Students'
   StudentID=Column(Integer, primary_key=True)
   name=Column(String)
   age=Column(Integer)
   marks=Column(Numeric)

Чтобы создать таблицу студентов с соответствующей структурой, выполните метод create_all (), определенный для базового класса.

base.metadata.create_all(engine)

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

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
sessionobj = Session()

Данные, хранящиеся в объекте Student, физически добавляются в базовую таблицу методом сеанса add ().

s1 = Student(name='Juhi', age=25, marks=200)
sessionobj.add(s1)
sessionobj.commit()

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

from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
from myclasses import Student, base
engine = create_engine('sqlite:///college.db', echo=True)
base.metadata.create_all(engine)

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
sessionobj = Session()
s1 = Student(name='Juhi', age=25, marks=200)
sessionobj.add(s1)
sessionobj.commit()

Консольный вывод

CREATE TABLE "Students" (
   "StudentID" INTEGER NOT NULL,
   name VARCHAR,
   age INTEGER,
   marks NUMERIC,
   PRIMARY KEY ("StudentID")
)
INFO sqlalchemy.engine.base.Engine ()
INFO sqlalchemy.engine.base.Engine COMMIT
INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
INFO sqlalchemy.engine.base.Engine INSERT INTO "Students" (name, age, marks) VALUES (?, ?, ?)
INFO sqlalchemy.engine.base.Engine ('Juhi', 25, 200.0)
INFO sqlalchemy.engine.base.Engine COMMIT

В session object также предоставляет метод add_all () для вставки более одного объекта в одну транзакцию.

sessionobj.add_all([s2,s3,s4,s5])
sessionobj.commit()

Теперь, когда в таблицу добавлены записи, мы хотели бы получать из нее данные, как это делает запрос SELECT. У объекта сеанса есть метод query () для выполнения задачи. Объект запроса возвращается методом query () в нашей модели Student.

qry=seesionobj.query(Student)

Используйте метод get () этого объекта Query для извлечения объекта, соответствующего данному первичному ключу.

S1=qry.get(1)

Пока этот оператор выполняется, соответствующий ему оператор SQL, отображаемый на консоли, будет следующим:

BEGIN (implicit)
SELECT "Students"."StudentID" AS "Students_StudentID", "Students".name AS 
   "Students_name", "Students".age AS "Students_age", 
   "Students".marks AS "Students_marks"
FROM "Students"
WHERE "Products"."Students" = ?
sqlalchemy.engine.base.Engine (1,)

Метод query.all () возвращает список всех объектов, по которым можно пройти с помощью цикла.

from sqlalchemy import Column, Integer, String, Numeric
from sqlalchemy import create_engine
from myclasses import Student,base
engine = create_engine('sqlite:///college.db', echo=True)
base.metadata.create_all(engine)
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
sessionobj = Session()
qry=sessionobj.query(Students)
rows=qry.all()
for row in rows:
   print (row)

Обновить запись в сопоставленной таблице очень просто. Все, что вам нужно сделать, это получить запись с помощью метода get (), присвоить новое значение желаемому атрибуту и ​​затем зафиксировать изменения с помощью объекта сеанса. Ниже мы меняем оценки ученика Джухи на 100.

S1=qry.get(1)
S1.marks=100
sessionobj.commit()

Удалить запись так же просто, удалив нужный объект из сеанса.

S1=qry.get(1)
Sessionobj.delete(S1)
sessionobj.commit()