Как использовать встроенную базу данных для хранения и обработки данных

Базы данных - отличный, безопасный и надежный способ хранения данных. Все основные реляционные базы данных имеют нечто общее - SQL - язык для управления базами данных, таблицами и данными. SQL - это обширная тема для обсуждения, особенно при работе с различными поставщиками баз данных, такими как Microsoft, IBM или Oracle, поэтому давайте начнем с SQLite - самой легкой системы баз данных.

Итак, что такое SQLite? Рад, что вы спросили. Это библиотека, которая предоставляет нам базу данных или систему управления реляционными базами данных. Термин «Lite» означает «легкий», что означает, что его легко настраивать и администрировать в мире баз данных.

Почему меня это должно волновать? Потому что вы можете получить опыт работы с базой данных без необходимости загружать программное обеспечение или создавать облачную базу данных, а затем выяснять, как подключиться к Python. Конечно, это не самый безопасный вариант, но он все же значительно превосходит CSV и файлы Excel, потому что никто не может изменить данные.

Сегодняшняя статья построена следующим образом:

  • Обзор проблемы
  • Создание таблиц
  • Создавать, читать, обновлять, удалять
  • Время тестирования
  • Заключение

Итак, мы рассмотрим основы - как создавать таблицы, вставлять данные, обновлять данные, удалять данные, получать все данные и получать данные на основе условия. Это все, что вам нужно для создания приложений.

Обзор проблемы

Вы любите фильмы? Да, я тоже. Сегодня мы сосредоточимся именно на этом, создав базу данных и таблицу для хранения названий фильмов и дополнительной информации. После того, как мы сделаем таблицу, нам нужно будет объявить пару функций:

  • Чтобы вставить фильмы
  • Чтобы получить все фильмы
  • Чтобы получить единственный фильм
  • Чтобы обновить отдельный фильм
  • Чтобы удалить один фильм

Звучит много, но это не так. Мы будем использовать Python для связи с базой данных SQLite и будем получать информацию о фильмах с IMDB.com.

Потрясающие! Давайте начнем!

Создание таблиц

Мы не можем хранить данные в базе данных напрямую - нам нужны таблицы. В базах данных хранятся таблицы, а в таблицах - данные. Наша процедура заключается в следующем - создайте таблицу фильмы только в том случае, если она еще не существует. Для этого потребуется два SQL-запроса: один для проверки, существует ли таблица с заданным именем, а другой для создания таблицы.

Во-первых, нам нужно импортировать библиотеку SQLite, установить соединение с базой данных и создать курсор. Следующий фрагмент делает это:

import sqlite3 
conn = sqlite3.connect('movies.db') 
c = conn.cursor()

База данных movies.db будет создана, если она не существует, и если она существует, устанавливается только соединение.

Затем мы объявим функцию, которая проверяет, существует ли таблица. Имя таблицы передается как параметр функции и возвращает True, если таблица существует, и False в противном случае:

def table_exists(table_name): 
    c.execute('''SELECT count(name) FROM sqlite_master WHERE TYPE = 'table' AND name = '{}' '''.format(table_name)) 
    if c.fetchone()[0] == 1: 
        return True 
    return False

Новые f-строки по какой-то причине не работают, поэтому мы должны вернуться к старому синтаксису - это не проблема, но имейте это в виду. Следующим шагом будет использование объявленной функции, чтобы проверить, существует ли таблица, и создать ее, если нет. Следующий фрагмент делает это:

if not table_exists('movies'): 
    c.execute(''' 
        CREATE TABLE movies( 
            movie_id INTEGER, 
            name TEXT, 
            release_year INTEGER, 
            genre TEXT, 
            rating REAL 
        ) 
    ''')

Потрясающие! На этом этот раздел заканчивается, а дальше мы перейдем к интересным вещам.

Создавать, читать, обновлять, удалять

Хорошо, у нас все настроено, и теперь самое время поработать с данными. Для начала нам понадобится функция, которая вставляет фильм в таблицу (часть Create). Его довольно легко написать, так как нам нужно выполнить один оператор INSERT и зафиксировать транзакцию. Вот код:

def insert_movie(movie_id, name, release_year, genre, rating): 
    c.execute(''' INSERT INTO movies (movie_id, name, release_year, genre, rating) VALUES(?, ?, ?, ?, ?) ''', (movie_id, name, release_year, genre, rating)) 
    conn.commit()

Вот и все! Мы оставим часть тестирования на потом, а теперь продолжим часть Читать.

Здесь мы объявим две функции: первая для получения всех фильмов, а вторая для получения только одной, указанной идентификатором фильма. Вы можете легко сжать логику в одну функцию, но я предпочел придерживаться этого подхода.

Вот функция для получения всех фильмов:

def get_movies(): 
    c.execute('''SELECT * FROM movies''') 
    data = [] 
    for row in c.fetchall(): 
        data.append(row) 
    return data

И фрагмент для получения одного фильма:

def get_movie(movie_id): 
    c.execute('''SELECT * FROM movies WHERE movie_id = {}'''.format(movie_id)) 
    data = [] 
    for row in c.fetchall():  
        data.append(row) 
    return data

Большой! Далее идет часть Обновление. Это посложнее. Мы хотим обновить элементы в соответствии с заданным идентификатором фильма, но что мы будем обновлять? Объявляем ли мы определенную функцию для каждого поля? Звучит неправильно. Выполним обновление со словарем.

Позвольте мне уточнить. Наша функция обновления будет принимать два параметра:

  • идентификатор фильма - идентификатор фильма, который вы хотите обновить
  • обновить словарь - пары ключ / значение для обновления

Ключи в словаре обновления должны быть названы в соответствии со столбцами таблицы, иначе возникнет исключение. Также нам нужно обработать обновление числовых и текстовых полей. Пока это самая сложная функция, но с ней можно справиться:

def update_movie(movie_id, update_dict): 
    valid_keys = ['name', 'release_year', 'genre', 'rating'] 
    for key in update_dict.keys():  
        if key not in valid_keys: 
            raise Exception('Invalid field name!') 
    for key in update_dict.keys(): 
        if type(update_dict[key]) == str: 
            stmt = '''UPDATE movies SET {} = '{}' WHERE movie_id = {}'''.format(key, update_dict[key], movie_id) 
        else: 
            stmt = '''UPDATE movies SET {} = '{}' WHERE movie_id = {}'''.format(key, update_dict[key], movie_id) 
        c.execute(stmt) 
    conn.commit()

Видеть? Это было не так уж и сложно. Закончим с частью Удалить. Это намного проще, чем предыдущий, поскольку нам нужно выполнить только один оператор и зафиксировать транзакцию. Вот код:

def delete_movie(movie_id): 
    c.execute('''DELETE FROM movies WHERE movie_id = {}'''.format(movie_id)) 
    conn.commit()

На этом мы завершаем эту часть. Далее мы проверим наши функции.

Время тестирования

Для начала вставим пару фильмов:

insert_movie(1, 'Titanic', 1997, 'Drama', 7.8) 
insert_movie(2, 'The Day After Tomorrow', 2004, 'Action', 6.4) 
insert_movie(3, '2012', 2009, 'Action', 5.8) 
insert_movie(4, 'Men in Black', 1997, 'Action', 7.3) 
insert_movie(5, 'World War Z', 2013, 'Romance', 10)

Выполнение этих пяти строк ничего не выводит на консоль, чего и следовало ожидать - мы только вставляем данные в таблицу. Затем мы воспользуемся нашей предопределенной функцией, чтобы получить все фильмы:

print(get_movies())

Потрясающие! Давайте теперь возьмем только один фильм:

print(get_movie(2))

Это было довольно просто. Теперь посмотрим, как обновить фильм. Последнему из вставленных, World War Z, была намеренно присвоена оценка 10 и жанр Romance, поэтому давайте изменим это:

update_movie(5, {'genre': 'Horror', 'rating': 7.0})

Теперь все имеет смысл. Осталось только удалить фильм. Давайте посмотрим, как это сделать:

delete_movie(3)

Это ничего не возвращает - как и ожидалось. Мы можем быстро получить все фильмы, чтобы увидеть, работает ли функция удаления:

И все работает - все работает как рекламируется. Давайте подведем итоги в следующем разделе.

Прежде чем ты уйдешь

Надеюсь, мне было легко следить за мной. Мы рассмотрели основы и оставили много вещей нетронутыми. Этого все еще достаточно для создания базовых приложений или API на основе баз данных, но подробнее об API в другой раз.

Не стесняйтесь расширять это, добавлять новые функции или таблицы или улучшать общее качество кода.

Спасибо за прочтение.

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

Первоначально опубликовано на https://www.betterdatascience.com 1 октября 2020 г.