Лет десять назад, когда я занимался разработкой iOS, еще не было устоявшихся решений для работы с базами данных мобильных приложений, так что мне пришлось реализовывать свою собственную БД. Выбор пал на SQLite, упрощенный механизм для управления реляционными базами данных.
Когда я в рамках своей деятельности частично переключился на науку о данных, то с радостью узнал, что в Python также есть API для использования SQLite. Важно отметить, что pandas, ведущая библиотека для обработки данных, предоставляет соответствующие функциональности для взаимодействия с разными базами данных, в том числе и SQLite. Совместное их применение позволяет выполнять множество действий, связанных с локальным хранением и управлением данными. В данной статье мы рассмотрим ряд основных операций.
1. Подключение к базе данных
Для работы с базой данных SQLite воспользуемся встроенным модулем sqlite3
, который предоставляет полный набор стандартных операций. В следующем примере рассмотрим способ подключения к БД:
import sqlite3
con = sqlite3.connect("test.db")
Вызывая функцию connect
мы достигаем 2 целей:
- Модуль подключается к базе данных
test.db
. Если ее не существует, он создает одноименную БД в текущей директории. - Вызов данной функции создает объект
Connect
, представляющий БД. С этого момента все связанные с ней операции выполняются с использованием объектаConnection
.
Если вы не намерены иметь дело с физической тестовой БД, то модуль может создать базу данных в памяти, выполнив следующий код.
con_memory = sqlite3.connect(":memory:")
В рамках данного руководства мы будем оперировать объектом con
, связанным с test.db
.
2. Создание новой таблицы и внесение записей
Начнем с заполнения БД данными. Допустим, у нас должно быть 2 поля данных (имя и балл) и 4 записи, как показано ниже:
names = ['John', 'Mike', 'Jane', 'Bella']
grades = [90, 95, 92, 98]
Следующий код показывает, как создать таблицу и соответствующим образом внести в нее записи.
# Создаем курсор
cur = con.cursor()
# Создаем таблицу с именем transcript
cur.execute("CREATE TABLE transcript (name text, grade integer);")
# Вставляем записи
cur.executemany("INSERT into transcript values (?, ?)", zip(names, grades))
# Выполняем все транзакции
con.commit()
- Как и в случае с другими базами данных все начинается с создания курсора для выполнения инструкций SQLite. Обратите внимание, что можно использовать нестандартные методы
execute
иexecutemany
непосредственно для объектаConnect
, чтобы код выглядел чище. Тем не менее, руководствуясь своей внутренней логикой, Python все равно сгенерирует для вас курсор. Выбор за вами — создавать его явно или нет. - Для создания таблицы в БД SQLite применяем
CREATE TABLE table_name (field0 field0_type, field1 field1_type, …)
. На сайте SQLite предоставлена информация о поддерживаемых типах данных. Кратко перечислим их: текст, целые числа, двоичный большой объект BLOB, позволяющий сохранять бинарные данные, и вещественный тип Real. Отметим, что SQLite не располагает логическим типом, поэтому для обозначения таких значений можно воспользоваться целыми числами 0 и 1. - Для внесения только одной записи просто вызываем
cur.execute(“INSERT into transcript values (‘John’, 90)”)
. Однако если в одном вызове функции нужно добавить несколько из них, то следует задействовать методexecutemany
. В нем шаблон инструкции SQL передается вместе сiterator
, чьи элементы последовательно добавляются в шаблон. - Чтобы отправить все транзакции для обновления базы данных, вызываем метод
commit
для объектаcon
.
3. Запрос записей
Аналогичным способом можно запросить записи, а именно отправить нужную инструкцию SQL, воспользовавшись методом execute
. Рассмотрим пример запроса записей, упорядоченных по оценкам:
>>> cur.execute("select * from transcript order by grade desc")
<sqlite3.Cursor object at 0x1103b5ea0>
Нельзя не заметить, что вместо ожидаемых всех записей вызов execute
возвращает тот же самый объект cursor
. После выполнения инструкции SELECT
с курсором можно работать как с итератором. Поэтому включаем его в конструктор списка для отображения всех записей.
>>> list(cur)
[('Bella', 98), ('Mike', 95), ('Jane', 92), ('John', 90)]
Как вариант, у объекта cursor
есть встроенные методы fetchall
и feathone
. Первый отображает все записи, а второй — только одну определенную из них. Отметим, что для извлечения возвращаемого значения из вызова execute
используются нижние подчеркивания.
>>> _ = cur.execute("select * from transcript order by grade desc")
>>> cur.fetchall()
[('Bella', 98), ('Mike', 95), ('Jane', 92), ('John', 90)]
>>> _ = cur.execute("select * from transcript order by grade desc")
>>> cur.fetchone()
('Bella', 98)
4. Изменение записей
Для обновления записей нужен следующий синтаксис инструкции SQL: update table_name set field_name=new_value, another_field=new_value where condition
. Задействуем его для изменения балла Джона:
>>> cur.execute("update transcript set grade = 100 where name = 'John'")
<sqlite3.Cursor object at 0x1103b5ea0>
>>> list(cur.execute("select * from transcript order by grade desc"))
[('John', 100), ('Bella', 98), ('Mike', 95), ('Jane', 92)]
Как видно, данная операция прошла успешно, изменив порядок имеющихся баллов.
5. Удаление записей
Для удаления записей предназначен вот такой синтаксис инструкции SQL: delete from table_name where condition
. Важно не пропустить условие condition
, иначе вы удалите все строки в таблице, что в большинстве случаев весьма не желательно. Рассмотрим пример:
>>> _ = cur.execute("delete from transcript where name='John'")
>>> list(cur.execute("select * from transcript order by grade desc"))
[('Bella', 98), ('Mike', 95), ('Jane', 92)]
Как видно, были удалены записи, связанные с John
.
6. Чтение данных SQLite с помощью Pandas
С pandas управление базой данных SQLite превращается в увлекательный процесс. Она предоставляет функцию read_sql
, позволяющую напрямую выполнять инструкции SQL, не заботясь о внутренней инфраструктуре.
>>> import pandas as pd
>>> df = pd.read_sql("select * from transcript", con)
>>> df
name grade
0 Mike 95
1 Jane 92
2 Bella 98
По сути, вызов данной функции создает DataFrame
, откуда вы можете извлекать разнообразные методы, предоставляемые библиотекой pandas.
Кто-то, возможно, сталкивался с такими функциями pandas, как read_sql_table
и read_sql_query
. Фактически функция read_sql
— это обертка вокруг них. Она анализирует входные данные и вызывает соответствующую функцию. Таким образом, на повседневной основе можно просто задействовать read_sql
, доверив pandas всю тяжелую работу.
7. Обратная запись DataFrame в SQLite
После обработки данных с помощью pandas самое время осуществить обратную запись DataFrame в БД SQLite для долгосрочного хранения. На этот случай в pandas есть метод to_sql
. Обратимся к соответствующему примеру:
>>> df['gpa'] = [4.0, 3.8, 3.9]
>>> df.to_sql("transcript", con, if_exists="replace", index=False)
>>> list(cur.execute("select * from transcript order by grade desc"))
[('Bella', 98, 3.9), ('Mike', 95, 4.0), ('Jane', 92, 3.8)]
- В отличие от
read_sql
, функции из библиотеки pandas,to_sql
является методом классаDataFrame
, вследствие чего он непосредственно вызывается объектомDataFrame
. - В методе
to_sql
указывается таблица, в которую сохраняетсяDataFrame
. - Отметим важность параметра
if_exists
, так как по умолчанию ему задается значение“fail”
. Это значит, что если таблица уже существует, вы не сможете записать в нее текущийDataFrame
, поскольку будет вызвана ошибкаValueError
. В рассматриваемом примере требуется заменить существующую таблицу из-за изменения средних баллов оценок, поэтому параметруif_exisits
устанавливается значение“replace”
. - В результате установки
index=False
индекс объектаDataFrame
просто игнорируется при сохранении в таблицу. По своему принципу данное действие аналогично методуto_csv
, с которым вы наверняка знакомы лучше.
Заключение
В статье был проведен обзор основных операций с базой данных SQLite при непосредственном участии встроенной библиотекой Python sqlite3. Как мы уже убедились, с помощью предоставляемых методов можно без труда выполнять стандартные операции SQL, такие как внесение, изменение и удаление записей. По сути, уже имеющиеся знания SQL во многом облегчают процесс обучения.
Не обошли мы своим вниманием и принцип взаимодействия pandas с БД SQLite. Запомнить его легко: read_sql
предназначен для извлечения данных из нее, а to_sql
выгружает их туда обратно. Иначе говоря, если предположить, что вашим основным инструментом обработки данных является pandas, то относительно базы данных SQLite read_sql
служит для вывода данных, а to_sql
— для ввода.
Читайте также:
- 4 способа добавления колонок в датафреймы Pandas
- 9 первоклассных функций Pandas Python для работы с данными
- 6 упущений в курсе науки о данных
Читайте нас в Telegram, VK и Дзен
Перевод статьи Yong Cui: From SQLite to Pandas — 7 Essential Operations You Need to Know