Сегодня познакомимся с интересным инструментом - NoSQL базой данных. Ранее мы мучали MySQL и подобные базы, которые требуют много внимания к SQL-запросам и структуре таблицы. Теперь мы познакомимся с идеальной базой данных для не структурированной информации. То есть мы избавимся от строгого синтаксиса и сможем легко дополнять записи новой информацией. В этом огромный плюс NoSQL-базы для написания различных ботов, которые в дальнейшем будут масштабироваться.
Подготовка
Сначала установим саму MongoBD: переходим на официальный сайт Mongo по ссылке и скачиваем сервер версии 6.0.3 под вашу операционную систему.
Для корректной установки следуйте примерам на скриншотах:
Важно тут выбрать пункт “Complete”. Этот пункт поставит все стандартные настройки и модули, что для начала нам подойдет. Потом, если будете изучать эту БД, сможете настраивать под себя:
В этом пункте важно поставить галочку на “Install MongoDB Compass” - на компьютер установится графический интерфейс для взаимодействия с СУБД.
После установки нам открывается программа MongoDB Compass, где уже вставлены данные для подключения к установленному серверу. Нажимаем кнопку "connect", и мы в нем:
Ниже пример как можно создать базу данных и коллекцию. Коллекции – это аналог таблиц в SQL-базах. В них мы храним информацию, которая нам нужна.
Установка MongoClient и код на Python
Для Windows:
pip install pymongo faker
Для MacOS:
python pip install pymongo faker
Для знакомства с СУБД MongoDB нам хватит сделать несколько методов, таких как: добавление пользователя, получить всю коллекцию, изменить какое-то значение, поиск, по заданным критериям и на этом все. Если вам будет интересна эта СУБД, вы сможете самостоятельно ознакомиться с другими её возможностями.
Анонсы всех видео, статей и полезностей - в нашем Telegram🔥
Присоединяйтесь, обсуждайте и автоматизируйте!
У нас будет два файла - pymongoAPI.py и main.py (призываю вас всегда разделять проект на логические модули – это правильный тон в мире программистов Python). Первый файл будет отвечать за взаимодействие с БД, а во втором мы будем пытаться добавлять новые значения и что-то менять.
Импорты:
from pymongo import MongoClient
Для всего взаимодействия с MongoDB потребуется только сам клиент, который и импортируем.
Класс взаимодействия с MongoDB:
class MongoDB(object):
def __init__(self, host: str = 'localhost',
port: int = 27017,
db_name: str = None,
collection: str = None):
self._client = MongoClient(f'mongodb://{host}:{port}')
self._collection = self._client[db_name][collection]
def create_user(self, user: dict):
try:
if self._collection.find_one({"username": user.get('username')}) == None:
self._collection.insert_one(user)
print(f"Added New user: {user.get('username')}")
else:
print(f"User: {user.get('username')} in collection")
except Exception as ex:
print("[create_user] Some problem...")
print(ex)
def get_all_users(self):
try:
data = self._collection.find()
print("Get all users")
return data
except Exception as ex:
print("[get_all] Some problem...")
print(ex)
def find_by_username(self, username: str):
try:
data = self._collection.find_one({"username": username})
print("Get user by username")
return data
except Exception as ex:
print("[find_by_username] Some problem...")
print(ex)
def change_user(self, username: str, key: str, value: str):
try:
if self._collection.find_one({"username": user.get('username')}) is not None:
self._collection.update_one({"username": username}, {"$set": {key: value}})
else:
print(f'User: {username} not find')
except Exception as ex:
print("[change_user] Some problem...")
print(ex)
Разберёмся что за чем идет.
__init__ — это конструктор, он принимает в себя ip адрес сервера, порт, название базы данных и название коллекции. Он создает подключение к серверу и записывает в отдельную внутреннюю переменную. Дальше отдельно вытягивает в переменную нашу базу данных. Часто спрашивают зачем ставить нижней прочерк перед полем – это нужно, чтобы показать другим разработчикам, который показывает, что его трогать не надо (так принято показывать в Python приватные переменные).
Create_user – «кушает» словарь, это связанно с тем, что мы будем сразу передавать нового пользователя. Можно формировать его и внутри метода, но так проще. Сразу скажу, что все запросы к базам данных следует оборачивать в try… except, потому что в случае ошибки у нас не будет «падать» программа. В реальной жизни если из-за этой ошибки пользователи не смогу воспользоваться функциями, у вас могут быть проблемы.
Теперь переходим к сути. Обращаемся к методу find_one для проверки, существует ли пользователь в коллекции. Внутрь мы передаем словарь ключ (искомое поле) и значение. Если нам в ответ вернется None, то значит такого значения не существует, ну и если словарь, то значит пользователь существует (сразу отмечу, что username у нас будут индивидуальным значением, то есть не будет повторяться).
Дальше обращаемся к insert_one и передаем словарь пользователя. Чтобы видеть ошибки, мы делаем выводы в консоль о выполненном действии и в случае ошибки показываем модуль с ошибкой.
Get_all_users – с помощью этого метода будем выводить все записи в коллекции. Обращаемся к объекту коллекции и применяем метод find, без каких-либо значений. В ответ мы получаем массив значений и возвращаем его из метода.
Find_by_username – теперь будем искать по уникальному значению в виде username. Принимаем искомого пользователя и обращаемся к методу коллекции find_one. Он будет выводить первое совпадение и возвращать его словарем, если пользователя не существует, то вернется None.
Change_user – последний метод на сегодня, он будет менять значение. Принимает в себя username, key (изменяемое значение) и value (новое значение). В начале идет проверка на наложение пользователя в коллекции, потом используется update_one.
Что же это такое, метод, предоставляемый объектом коллекции для обновления записи? Первым значением идет словарь для поиска по значение, потом второй с служебным оператором $set с вложенным вторым словарем, внутри которого находится ключ и его новое значение (подробнее об служебных операторах по ссылке).
Main.py
Теперь идем проверять наш класс. Будем рассматривать код по строчкам, чтобы можно было посмотреть все по очереди и отслеживать, что меняется в БД. Импортируем наш MongoDB из файла mongoAPI. Так же библиотеку для создания несуществующих пользователей.
from mongoAPI import MongoDB
import faker
Дальше создаем объект dbase на основе нашего класса, передаем в него название БД и коллекции с которой будем работать:
dbase = MongoDB(db_name='article', collection='user')
Так же не стоит забывать про объект для создание «фейковых» пользователей:
faker_obj = faker.Faker()
Создаем наш фейковый профиль и посмотрим вывод в консоль:
user_profile = faker_obj.simple_profile()
user_profile['birthdate'] = user_profile['birthdate'].strftime('%d/%m/%Y')
print(user_profile)
Словарь состоит из логина, имени, пола, адреса, почты и даты рождения:
{'username': 'dparker', 'name': 'Megan Morris', 'sex': 'F', 'address': '15074 Conner Lane\nDavidshire, ME 67230', 'mail': 'leslie72@gmail.com', 'birthdate': '24/04/2017'}
Пробуем добавить его в коллекцию:
dbase.create_user(user_profile)
Выводы в консоль:
{'username': 'ronald44', 'name': 'Carrie Armstrong', 'sex': 'F', 'address': '0829 Cook Key Apt. 678\nKatherinestad, CA 73382', 'mail': 'tammy73@hotmail.com', 'birthdate': '24/08/1998'}
Added New user: ronald44
Как выглядит все в коллекции:
Тут может возникнуть вопрос, что за значение _id? Это уникальный ID, который автоматически создает MongoDB. Можно провести аналогию с Primary Key в MySQL.
Давайте добавим пару случайных пользователей с помощью библиотеки faker и цикла for. Выглядит все так:
for _ in range(3):
user_profile = faker_obj.simple_profile()
user_profile['birthdate'] = user_profile['birthdate'].strftime('%d/%m/%Y')
dbase.create_user(user_profile)
Добавили пользователей: xwilliams, kylewilliams и obrowning. Так это выглядит в коллекции:
Чтобы посмотреть полную сводку из коллекции надо будет воспользоваться циклом for. Это связано с тем, что в ответ нам идет объект Cursor:
result = dbase.get_all_users()
for i in result:
print(i)
Вывод в консоль:
Get all users
{'_id': ObjectId('63790f4edc6a4ce30ed44398'), 'username': 'ronald44', 'name': 'Carrie Armstrong', 'sex': 'F', 'address': '0829 Cook Key Apt. 678\nKatherinestad, CA 73382', 'mail': 'tammy73@hotmail.com', 'birthdate': '24/08/1998'}
{'_id': ObjectId('637910f07d126aae084a4310'), 'username': 'xwilliams', 'name': 'Erin Simmons', 'sex': 'F', 'address': 'PSC 0729, Box 2069\nAPO AP 14417', 'mail': 'suzanne49@hotmail.com', 'birthdate': '05/04/1918'}
{'_id': ObjectId('637910f07d126aae084a4311'), 'username': 'kylewilliams', 'name': 'Jeffrey Miller', 'sex': 'M', 'address': '977 Santos Turnpike Apt. 039\nNew Cynthia, FM 81301', 'mail': 'christopher50@gmail.com', 'birthdate': '16/06/2016'}
{'_id': ObjectId('637910f07d126aae084a4312'), 'username': 'obrowning', 'name': 'Amy Thompson', 'sex': 'F', 'address': '041 Leah Locks Suite 280\nReedport, MI 56259', 'mail': 'vargassarah@hotmail.com', 'birthdate': '25/08/1915'}
Поиск человека по логину:
print(dbase.find_by_username('username'))
Вывод в консоль:
Get user by username
{'_id': ObjectId('63790f4edc6a4ce30ed44398'), 'username': 'ronald44', 'name': 'Carrie Armstrong', 'sex': 'F', 'address': '0829 Cook Key Apt. 678\nKatherinestad, CA 73382', 'mail': 'tammy73@hotmail.com', 'birthdate': '24/08/1998'}
Теперь изменим пользователю имя на "тест":
dbase.change_user('ronald44', 'name', 'test')
После запуска мы увидим в коллекции следующее:
Заключение
Сегодня мы тестировали СУБД MongoDB - сделали тестовое добавление коллекции и попробовали вносить в базу изменения.
Как вы видите, Mongo очень удобна и гибка, что позволяет легко масштабировать из маленького проекта в большой. Советую вам изучить её более подробно.
Полезные ссылки
Документации библиотеки pymongo: https://pymongo.readthedocs.io/en/stable/
Подробный курс на ютубе: https://www.youtube.com/playlist?list=PL6plRXMq5RABbVCM0dn23PTKO13WcXnbf
Комментарии