Приветствую, друзья!
Сегодня у меня для вас незапланированная публикация.
В процессе работы над новой статьей из цикла по FastAPI, я создавал примеры взаимодействия с базой данных через JSON, включая операции по извлечению, добавлению, изменению данных и другие.
В результате накопилось большое количество кода, который оказался избыточным, особенно с учётом того, что скоро я планирую перейти к описанию более серьёзного взаимодействия FastAPI с полноценной базой данных (SQLAlchemy с миграциями через Alembic). Поэтому я решил вынести весь код взаимодействия с JSON в отдельную библиотеку.
Так появилась json_db_lite.
Эта библиотека будет полезна в контексте FastAPI как отправная точка для знакомства с взаимодействием FastAPI и баз данных. В других проектах функционал json_db_lite также может оказаться весьма полезным.
Примеры Использования
Допустим, вам нужно парсить большой объем товаров с интернет-магазина (например, 5000 товаров). Категорий может быть много, и каждая категория имеет свои уникальные характеристики. На начальном этапе вы не знаете, какие характеристики собирать, а задача стоит в том, чтобы собрать всю возможную информацию по товарам.
Теперь вы можете спарсить весь сайт, собрав данные в формате JSON, не беспокоясь о количестве ключей в каждом словаре товара. После завершения сбора данных вы сможете легко вывести все данные, удалить ненужные ключи и записать их в стандартную SQL базу данных.
Если вы знакомы с NoSQL базами данных, такими как MongoDB, возможно, этот пример не будет для вас интересен. Однако я старался сделать библиотеку полезной для каждого, чтобы каждый нашел в ней что-то для себя.
Зачем Нужен JSON
Прежде чем мы приступим к установке библиотеки и разбору её синтаксиса, давайте разберемся, что такое JSON и зачем он нужен.
JSON (JavaScript Object Notation) — это стандартный текстовый формат для хранения и передачи структурированных данных. Он основан на синтаксисе объекта в JavaScript, но не привязан к этому языку.
Проще говоря, JSON — это основная структура данных, которая используется для общения между приложениями (клиентом и сервером). Благодаря удобной структуре "ключ — значение", JSON используется во всех языках программирования, хотя может называться по-разному. В Python, например, это словари (dict).
Возможности Библиотеки
json_db_lite позволяет:
Создавать JSON файл при инициализации класса (можно расценивать как создание базы данных).
Добавлять новые записи.
Получать все записи.
Очищать базу данных.
Удалять записи по ключу.
Обновлять записи по ключу.
Установка
Библиотека опубликована на PyPi, поэтому вы можете установить её с помощью следующей команды:
pip install --upgrade json_db_lite
Импорт и инициализация
from json_db_lite import JSONDatabase
# Инициализация базы данных
db_client = JSONDatabase('db.json')
После инициализации класса будет создан пустой JSON файл. Вы можете указать название файла или передать путь к папке, чтобы файл был создан там. Этот файл и будет являться вашей простой базой данных.
Примеры использования
Добавление данных
def add_data_to_db():
# массовое добавление
db_client.add_records([{"id": 1, "name": "Sara"},
{"id": 2, "name": "Mark"},
{"id": 3, "name": "Charlie"},
{"id": 4, "name": "David"}
])
# добавление одной записи
db_client.add_records({"id": 5, "name": "Alex"})
Метод принимает словарь или список словарей, добавляя записи в JSON.
Извлечение всех данных
def get_all_data():
# возвращаем все данные
return db_client.get_all_records()
Извлечение данных по конкретному ключу
def get_data(key='id', value=4):
# возвращаем данные по ключу
return db_client.find_records_by_key(key, value)
Функция возвращает список словарей, даже если возвращается одно значение.
Обновление данных
def update_data():
# обновляем данные по ключу у одного словаря
db_client.update_record_by_key(upd_filter={"id": 4}, new_data=[{"name": "Alex"}, {"age": 31}])
# обновляем данные по ключу у одного словаря
db_client.update_record_by_key(upd_filter={"name": "Alex"},
new_data=[{"age": 40}, {"job": "python developer"}])
Метод универсален. В качестве upd_filter
передается словарь формата "ключ-значение" для фильтрации. В new_data
можно передать список словарей или отдельный словарь. При отсутствии связки "ключ-значение", но при совпадении с фильтром, метод добавит новую связку. Если связка присутствует, то выполнит обновление.
Удаление записей
def dell_data():
# удаляем данные по ключу
db_client.delete_record_by_key(key="name", value="Alex")
После выполнения этого кода будут удалены все словари, у которых name = Alex
.
Очистка Базы Данных
def dell_all_data():
db_client.clear_database()
Заключение
Несмотря на свою простоту, библиотека получилась достаточно гибкой и универсальной. О новостях и обновлениях библиотеки я буду сообщать в своём телеграм-канале «Легкий путь в Python».
Репозиторий проекта на GitHub: JsonDatabase.
Надеюсь, что данная информация была вам полезной. Если это так, поддержите меня лайком, подпиской или комментарием. Ваше внимание и поддержка помогут мне продолжать выпускать полезные и универсальные библиотеки.
Благодарю за внимание!
Комментарии (15)
kalbas
03.07.2024 11:50Для каких целей может понадобиться такая странная библиотека? Пример с парсингом не совсем корректный, потому что запись с помощью вашей библиотеки как минимум не параллелизуется.
yakvenalex Автор
03.07.2024 11:50А для каких задач подходит чистый модуль JSON? Он с коробки как бы не асинхронный. Хочу обратить внимание. Я вообще не выходил за пределы чистого JSON. Или вы будете утверждать что чистый JSON Python нельзя нигде использовать?
kalbas
03.07.2024 11:50+1При чем здесь синхронный модуль json и параллелизация записи в базу? У вас тут не решена проблема гонок, как ваши парсеры будут одновременно писать в файл?
yakvenalex Автор
03.07.2024 11:50Понял о чем вы)
Уже выше писал по данному поводу. Если спрос на библиотеку будет - все можно улучшить и дописать. Библиотека же гвоздями не прибита к текущей версии)
Просто будет ли смысл, в целом, время тратить на это, если инструмент окажется никому не нужным. В этом вопрос.
Вот, к примеру. Даже на этот вариант было потрачено достаточно много времени. В целом код, описание и прочее. Уже сейчас публикация получила 2 диза и, насколько я понимаю, не последние.
Можно выделить пару дней. Заморочиться. Прописать в коде вообще все что тут вы и прочие комментаторы предложили, чтоб нарваться на очередной хейт. В чем смысл?)
Сейчас библитоеку стоит расценивать как проба пера - "нужен инструмент" или "не нужен". Лично я для больших парсеров в формате JSON использую MongoDB с библиотекой motor, но а для мелких парсеров и задач по взаимодействию с JSON на Python теперь буду использовать свою библиотеку.
При любом раскладе это удобнее чем чистый JSON и функционала больше. А под запрос от аудитории добавлю в библиотеку новые функции или допилю старые.
kalbas
03.07.2024 11:50+1В этом и был мой изначальный вопрос, лично я не вижу проблем, которые решает эта библиотека. Вместо нее можно ограничиться одним контекстным менеджером, который будет открывать файл, преобразовывать в словарь и закрывать-записывать.
ponikrf
03.07.2024 11:50Скажу честно - не совсем понимаю зачем это на питоне. Но в JSе есть такая необходимость. Например есть такая база как NeDB - несмотря на то что она уже давно не разрабатывается, ее продалжают качать и качать. Потому что далеко не всегда нужна база уровня MySql или MongoDB. К сожалению я даже и не знаю сейчас активной библиотеки на JS которая бы развивалась в этом направлении. Последнее чем пользовался - LokiJS. Нужна она была мне для создания локальной базы для сверки с внешней Api подобной базой и выявления разницы между ними.
Спрос на такие базы не уменьшается, а вот по серьезному поддерживать их особо люди не хотят. Все таки сложное это дело.
yakvenalex Автор
03.07.2024 11:50Бывают разные задачи в Python и в их рамках часто приходится с JSON взаимодействовать. Как самый яркий пример - это разработка бэкенда для веб-прилождений на Python (FastApi, Flaskи Django). Всё общение по API идет в контексте JSON (как передача, так и обработка данных).
Ещё, по крайней мере в моей практике, часто приходится работать с готовыми JSON файламы.
Кроме того. Не зря же JSON встроенная библиотека)
kalbas
03.07.2024 11:50А в чем отличие js от python в данном контексте? Речь же про js-бэкенд?
ponikrf
03.07.2024 11:50Разница в том, что JS может выполнятся на стороне браузера и такие базы работают в том числе и в браузере. JS для таких задач как ложка-вилка)
Ну если таким пользуются на питоне - ок.
kalbas
03.07.2024 11:50Тогда и речь нужно вести о client-side базах и server-side, вопрос то не в языке. В браузере то у вас всегда есть IndexedDB (наверное я правильно понял что это, я довольно далек от фронта). А на сервере всегда и везде есть sqllite (и не только на сервере кстати), который уже и JSON довольно продолжительное время поддерживает.
YAKOROLEVAZAMKA
03.07.2024 11:50Библиотека предполагает ETL-подход, но для неструктурированных данных кажется проще использовать ELT (Extract - Load - Transform), т.е. сохранить данные as is в какой-нибудь Postgres в поле с типом json, а потом уже обрабатывать это поле
Т.е. грубо говоря если с помощью библиотеки делаем парсинг json, а потом (как обычно бывает) туда попадают новые ключи \ уходят старые то мы на выходе получим некорректный json. В случае с ELT-подходом просто правим парсер (вместо перезагрузки данных за N-период + так же правки парсера)
Dominux
03.07.2024 11:50Очередная статья от "Опытного Python-разработчика с многолетним стажем" (хотя странно было бы читать статьи по Python от человека, знакомым с ним менее года)
взаимодействием FastAPI и баз данных
Простите, что? FastAPI - роутер, а не ОРМ/драйвер к бд. Я даже не стану говорить, что это должны быть разные и абсолютно не знающие друг о друге компоненты системы, но до таких тем видимо ещё далеко
Допустим, вам нужно парсить большой объем товаров с интернет-магазина
Как это вообще относится к FastAPI? Я ничего не хочу сказать, но мне кажется, вы действительно несколько лет занимались парсингом и созданием ТГ ботов, а неделю назад узнали о существовании FastAPI и Docker
В целом, какой смысл писать данную библиотеку на Python и только для Python? Она же будет весьма медленной и прожерливой по памяти. Такие вещи реализуют на языках без рантайм примочек вроде интерпретации и gc, а затем через FFI используют где хотите, в то же самом Python.
P.s.: очевидный вопрос в стиле "зачем эта либа вообще нужна" задавать не буду, т.к. уже итак все поинтересовались. Может быть всё-таки вернётесь к парсингу инфы с маркетплейсов и ТГ ботам, а не будете продвигать никому не нужный модуль с несколькими CRUD-функциями под видом "классной и универсальной библиотеки". Я понимаю, вы вероятно работали все это время в сфере фриланса и привыкли рекламировать свои решения, какими на самом деле простыми и недалёкими они ни были
Dair_Targ
Как учебное пособие или результат лабы - отлично (только добавьте py.typed!).
Для реальных задач - отказать:( уж очень много недочётов (например: вычитывает все данные в память, полно fullscan-операций, нет покрытия тестами - test_database.py явно не оно:), нет проверки заявленных версий питона через tox)
yakvenalex Автор
В плане недочетов соглашусь, но всему свое время. Сейчас посмотрю, в целом, нужна ли данная библиотека пользователям. Если нужна, то потихоньку недочеты закрою, а если нет, то и так сойдет)