Создание базы данных MongoDB
Узнайте, как создать базу данных MongoDB в Python с помощью PyMongo: подключение, отложенное создание, просмотр баз данных и типичные ошибки.
MongoDB не создаёт базу данных до тех пор, пока вы фактически не запишете в неё данные. Такое поведение «отложенного создания» является намеренным и становится одним из первых сюрпризов для новых пользователей. В этой главе мы разберём, как подключиться к серверу MongoDB с помощью драйвера Python pymongo, когда именно создаётся база данных, как убедиться в её существовании и как удалить тестовые базы данных.
Необходимые условия
- Установленный Python 3.8 или более поздней версии
- Работающий сервер MongoDB (локальный или удалённый). Если вы ещё не установили MongoDB, сначала ознакомьтесь с главой MongoDB Get Started.
- Установленный драйвер
pymongo:
pip install pymongoКак работает создание базы данных в MongoDB
В отличие от реляционных баз данных, в MongoDB никогда не выполняется инструкция CREATE DATABASE. Вместо этого:
- Вы обращаетесь к базе данных по имени через объект клиента.
- MongoDB сохраняет эту ссылку в памяти, но ничего не создаёт на диске.
- База данных физически создаётся в момент первой вставки документа или явного создания коллекции.
Это означает, что client["mydb"] всегда «успешен» — он возвращает объект Database независимо от того, существует ли mydb или нет.
Подключение к MongoDB
Импортируйте MongoClient и откройте соединение. Если MongoDB запущена на той же машине с настройками по умолчанию (хост localhost, порт 27017), можно вызвать MongoClient() без аргументов:
from pymongo import MongoClient
# Connect to the local MongoDB server (localhost:27017)
client = MongoClient()Для подключения к удалённому серверу или нестандартному порту передайте URI подключения:
# Generic URI form
client = MongoClient("mongodb://hostname:port")
# Example: remote host on port 27017
client = MongoClient("mongodb://db.example.com:27017")
# Example: with authentication
client = MongoClient("mongodb://username:[email protected]:27017")MongoClient использует пул соединений внутренне — создайте один клиент на приложение и переиспользуйте его для всех операций с базой данных.
Получение ссылки на базу данных
Обратитесь к базе данных через атрибут или с помощью словарной нотации:
# Both lines do exactly the same thing
db = client.my_database
db = client["my_database"]Используйте словарный стиль (client["name"]), когда имя базы данных содержит символы, недопустимые в идентификаторах Python, например дефисы.
На данном этапе база данных ещё не существует на сервере. Выведите список баз данных клиента для подтверждения:
print(client.list_database_names())
# Typical output: ['admin', 'config', 'local']
# 'my_database' is NOT listed yetСоздание базы данных путём вставки документа
Простейший способ материализовать базу данных — вставить один документ. Пример ниже создаёт базу данных bookstore и коллекцию books:
from pymongo import MongoClient
client = MongoClient()
db = client["bookstore"]
books = db["books"]
# Inserting the first document triggers physical database creation
result = books.insert_one({
"title": "The Pragmatic Programmer",
"author": "David Thomas",
"year": 1999
})
print("Inserted document id:", result.inserted_id)
print("Databases now:", client.list_database_names())После выполнения этого скрипта вы должны увидеть примерно такой вывод:
Inserted document id: 64a1e3b2c9f1234567890abc
Databases now: ['admin', 'bookstore', 'config', 'local']bookstore теперь отображается в списке, потому что в ней существует хотя бы один документ.
Проверка существования базы данных
Поскольку referenced база данных может существовать или не существовать, для проверки нужно изучить список, возвращаемый методом list_database_names():
from pymongo import MongoClient
client = MongoClient()
def database_exists(client, name):
return name in client.list_database_names()
print(database_exists(client, "bookstore")) # True (if created above)
print(database_exists(client, "no_such_db")) # FalseУдаление тестовой базы данных
Чтобы удалить базу данных (например, после тестирования), вызовите drop_database() на клиенте:
from pymongo import MongoClient
client = MongoClient()
client.drop_database("bookstore")
print("bookstore" in client.list_database_names()) # FalseЭто безвозвратно удаляет базу данных со всеми её коллекциями и документами. Запрос подтверждения не выводится.
Типичные ошибки
Опечатки не вызывают ошибок
Поскольку MongoDB создаёт базы данных по запросу, опечатка в имени базы данных незаметно создаёт вторую базу данных вместо того, чтобы вызвать ошибку:
# Intended: 'bookstore'
# Actual: 'bookstoree' — a new empty database that never gets data
db = client["bookstoree"]Чтобы избежать этого, всегда определяйте имена баз данных как константы в начале модуля:
DB_NAME = "bookstore"
db = client[DB_NAME]Пустые базы данных не отображаются
Если вы ссылаетесь на базу данных, но никогда не вставляете в неё данные, list_database_names() не включит её в список. Это может запутать при отладке — база данных «существует» как Python-объект, но не на диске.
Ошибки соединения проявляются поздно
MongoClient() завершается успешно даже если MongoDB не запущена. Ошибка соединения проявляется только при выполнении реального запроса (insert, find и т. д.). Оборачивайте реальные операции в блок try/except:
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
client = MongoClient(serverSelectionTimeoutMS=3000)
try:
# This forces a real network round-trip
client.admin.command("ping")
print("Connected to MongoDB")
except ConnectionFailure as e:
print("Could not connect:", e)Полный рабочий пример
Следующий самодостаточный скрипт демонстрирует все шаги, рассмотренные в этой главе:
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
DB_NAME = "demo_bookstore"
def main():
client = MongoClient(serverSelectionTimeoutMS=3000)
# Verify the connection
try:
client.admin.command("ping")
except ConnectionFailure as e:
print("MongoDB is not reachable:", e)
return
# Before any insert, the database does not appear in the list
print("Before insert:", DB_NAME in client.list_database_names())
db = client[DB_NAME]
books = db["books"]
# Insert a document — this creates the database
books.insert_one({"title": "Clean Code", "author": "Robert C. Martin"})
# Now the database is visible
print("After insert: ", DB_NAME in client.list_database_names())
print("Databases: ", client.list_database_names())
# Clean up
client.drop_database(DB_NAME)
print("After drop: ", DB_NAME in client.list_database_names())
if __name__ == "__main__":
main()Ожидаемый вывод (идентификатор документа будет отличаться):
Before insert: False
After insert: True
Databases: ['admin', 'config', 'demo_bookstore', 'local']
After drop: FalseСледующие шаги
- MongoDB Create Collection — узнайте, как создавать коллекции и понять отложенное создание на уровне коллекций.
- MongoDB Insert — вставка одного и нескольких документов в коллекцию.
- MongoDB Find — запрос документов из коллекции.