Operações básicas do MongoDB em Python
Avalie esse Início rápido
Gosta de Python? Quer começar a usar o MongoDB? Bem-vindo a este guia de início rápido! Mostrarei como configurar um banco de dados do Atlas com alguns dados de amostra para explorar. Em seguida, você criará alguns dados e aprenderá a lê-los, atualizá-los e excluí-los.
Você precisará dos seguintes itens instalados em seu computador para acompanhar este tutorial:
- Uma versão atualizada do Python 3. Escrevi o código neste tutorial no Python 3.8, mas deve funcionar bem na versão 3.6+.
- Um editor de código de sua escolha. Recomendamos PyCharm ou o VS Code gratuito com a extensão Python oficial.
Agora que você tem seu ambiente local configurado, é hora de criar um MongoDB database para trabalhar e carregar alguns dados de amostra que você pode explorar e modificar.
Você poderia criar um banco de dados em sua máquina de desenvolvimento, mas é mais fácil começar a usar o serviço hospedado do Atlas sem precisar aprender a configurar um MongoDB cluster.
Comece hoje mesmo com um cluster M0 no Atlas. É gratuito para sempre e é a maneira mais fácil de experimentar as etapas desta série de blogs.
Você precisará criar um novo cluster e carregá-lo com dados de amostra. Meu incrível colega Maxime Beugnet criou um tutorial em vídeo para ajudá-lo.
Se você não quiser assistir ao vídeo, as etapas são:
- Clique em "Comece gratuitamente".
- Insira seus dados e aceite os Termos de Serviço.
- Crie um cluster Starter.
- Selecione o mesmo provedor de nuvem com o qual você está acostumado ou deixe-o como está. Escolha uma região que faça sentido para você.
- Você pode alterar o nome do cluster, se quiser. Chamei o meu de "PythonQuickstart".
O provisionamento do cluster levará alguns minutos; portanto, enquanto espera, você pode passar para a próxima etapa.
Você deve configurar um virtualenv do Python que conterá as bibliotecas instaladas durante este início rápido. Existem várias maneiras diferentes de configurar virtualenvs, mas para simplificar as coisas, usaremos o incluído no Python. Primeiro, crie um diretório para manter seu código e seu virtualenv. Abra seu terminal,
cd
para esse diretório e execute o seguinte comando:1 # Note: 2 # On Debian & Ubuntu systems you'll first need to install virtualenv with: 3 # sudo apt install python3-venv 4 python3 -m venv venv
O comando acima cria um virtualenv em um diretório chamado
venv
. Para ativar o novo virtualenv, execute um dos seguintes comandos, de acordo com seu sistema:1 # Run the following on OSX & Linux: 2 source venv/bin/activate 3 4 # Run the following on Windows: 5 .\\venv\\Scripts\\activate
Para escrever programas Python que se conectem ao seu MongoDB database (não se preocupe, você definirá isso em um momento), você precisará instalar um driver Python – uma biblioteca que sabe como se comunicar com o MongoDB. No Python, você tem duas opções! O driver recomendado é PyMongo, que é o que abordarei neste Início Rápido. Se quiser escrever programas assíncronos com o MongoDB, você precisará usar uma biblioteca chamada Motor, que também é totalmente compatível com o MongoDB.
Para instalar o PyMongo, execute o seguinte comando:
1 python -m pip install pymongo[srv]==3.10.1
Para este tutorial, também usaremos uma biblioteca chamada
python-dotenv
para carregar a configuração, então execute o comando abaixo também para instalá-la:1 python -m pip install python-dotenv==0.13.0
Esperemos que seu MongoDB cluster tenha terminado de ser iniciado agora e provavelmente esteja em execução há alguns minutos.
As instruções a seguir estavam corretas no momento da escrita, mas podem ser alteradas, pois estamos sempre melhorando a Atlas user interface:
Na interface web do Atlas, você verá um botão verde na parte inferior esquerda da tela, dizendo "Get Started". Clique nele para ver uma lista de verificação de etapas para configurar seu banco de dados. Clique em cada um dos itens da lista (incluindo o item opcional "Load Sample Data") e isso ajudará você nas etapas de configuração.
Seguindo as etapas de "Comece a usar", crie um usuário com "Acesso de leitura e gravação a qualquer banco de dados". Você pode dar-lhe um nome de usuário e senha de sua escolha. Guarde-os, pois você precisará deles em breve. Use o botão "gerar senha segura automaticamente" para garantir que você tenha uma senha longa e aleatória que também seja segura para colar em sua string de conexão posteriormente.
Ao implantar um aplicativo com dados confidenciais, você só deve permitir o endereço IP dos servidores que precisam se conectar ao seu banco de dados. Para permitir o endereço IP da sua máquina de desenvolvimento, selecione "Acesso à rede", clique no botão "Adicionar endereço IP" e, em seguida, clique em "Adicionar endereço IP atual" e pressione "Confirmar".
A última etapa da lista de verificação "Comece a usar" é "Conecte-se ao seu cluster". Selecione "Conectar seu aplicativo" e selecione "Python" com uma versão "3.6 ou posterior".
Certifique-se de que a Etapa 2 tenha "Somente string de conexão" destacada e pressione o botão "Copiar" para copiar o URL para sua área de trabalho. Salve-o no mesmo local onde armazenou seu nome de usuário e senha. Observe que o URL tem
<password>
como espaço reservado para sua senha. Você deve colar sua senha aqui, substituindo todo o espaço reservado, incluindo os caracteres '<' and '>'.Agora é hora de escrever um código Python para se conectar ao seu MongoDB database!
Em seu editor de código, crie um arquivo Python no diretório do projeto chamado
basic_operations.py
. Digite o seguinte código:1 import datetime # This will be needed later 2 import os 3 4 from dotenv import load_dotenv 5 from pymongo import MongoClient 6 7 # Load config from a .env file: 8 load_dotenv() 9 MONGODB_URI = os.environ['MONGODB_URI'] 10 11 # Connect to your MongoDB cluster: 12 client = MongoClient(MONGODB_URI) 13 14 # List all the databases in the cluster: 15 for db_info in client.list_database_names(): 16 print(db_info)
Para executar isso, você precisará definir a variável de ambiente MONGODB_URI para a string de conexão obtida acima. Você pode fazer isso de duas maneiras. Você pode:
- Execute um comando
export
(ouset
no Windows) para definir a variável de ambiente sempre que você configurar sua sessão. - Salve o URI em um arquivo de configuração que nunca deve ser adicionado ao controle de revisão.
Mostrarei como usar a segunda abordagem. Lembre-se de que é muito importante não publicar acidentalmente suas credenciais no git ou em qualquer outro lugar, portanto, adicione
.env
ao seu arquivo .gitignore
se estiver usando o git. A biblioteca python-dotenv
carrega a configuração de um arquivo no diretório atual chamado .env
. Crie um arquivo .env
no mesmo diretório do seu código e cole a configuração abaixo, substituindo o URI do espaço reservado pelo seu próprio URI do MongoDB.1 # Unix: 2 export MONGODB_URI='mongodb+srv://yourusername:yourpasswordgoeshere@pythonquickstart-123ab.mongodb.net/test?retryWrites=true&w=majority'
O URI contém seu nome de usuário e senha (portanto, mantenha-o seguro!), e o nome do host de um servidor DNS que fornecerá informações ao PyMongo sobre seu cluster. Depois que o PyMongo recuperar os detalhes do seu cluster, ele se conectará ao servidor MongoDB primário e começará a executar queries.
Agora, se você executar o script Python, deverá ver uma saída semelhante à seguinte:
1 $ python basic_operations.py 2 sample_airbnb 3 sample_analytics 4 sample_geospatial 5 sample_mflix 6 sample_supplies 7 sample_training 8 sample_weatherdata 9 twitter_analytics 10 admin 11 local
Você acabou de conectar seu programa Python ao MongoDB e listar os bancos de dados em seu cluster! Se você não vir essa lista, talvez não tenha carregado com êxito os dados de amostra em seu cluster; talvez seja necessário voltar algumas etapas até que a execução desse comando mostre a lista acima.
No código acima, você usou o método
list_database_names
para listar os nomes dos bancos de dados no cluster. A instância MongoClient
também pode ser usada como um mapeamento (como um dict
) para obter uma referência a um banco de dados específico. Aqui está um código para dar uma olhada nas coleções dentro do banco de dados sample_mflix
. Cole-o no final do seu arquivo Python:1 # Get a reference to the 'sample_mflix' database: 2 db = client['sample_mflix'] 3 4 # List all the collections in 'sample_mflix': 5 collections = db.list_collection_names() 6 for collection in collections: 7 print(collection)
Ao executar este trecho de código, a saída deve ser a seguinte:
1 $ python basic_operations.py 2 movies 3 sessions 4 comments 5 users 6 theaters
Um banco de dados também se comporta como um mapeamento de coleções dentro desse banco de dados. Uma coleção é um bucket de documentos, da mesma forma que uma tabela contém linhas em um banco de dados relacional tradicional. O seguinte código procura um único documento na coleção
movies
:1 # Import the `pprint` function to print nested data: 2 from pprint import pprint 3 4 # Get a reference to the 'movies' collection: 5 movies = db['movies'] 6 7 # Get the document with the title 'Blacksmith Scene': 8 pprint(movies.find_one({'title': 'Blacksmith Scene'}))
Quando você executa o código acima, ele procura um documento chamado "Blacksmith Scene" na coleção "filmes". É mais ou menos assim:
1 {'_id': ObjectId('573a1390f29313caabcd4135'), 2 'awards': {'nominations': 0, 'text': '1 win.', 'wins': 1}, 3 'cast': ['Charles Kayser', 'John Ott'], 4 'countries': ['USA'], 5 'directors': ['William K.L. Dickson'], 6 'fullplot': 'A stationary camera looks at a large anvil with a blacksmith ' 7 'behind it and one on either side. The smith in the middle draws ' 8 'a heated metal rod from the fire, places it on the anvil, and ' 9 'all three begin a rhythmic hammering. After several blows, the ' 10 'metal goes back in the fire. One smith pulls out a bottle of ' 11 'beer, and they each take a swig. Then, out comes the glowing ' 12 'metal and the hammering resumes.', 13 'genres': ['Short'], 14 'imdb': {'id': 5, 'rating': 6.2, 'votes': 1189}, 15 'lastupdated': '2015-08-26 00:03:50.133000000', 16 'num_mflix_comments': 1, 17 'plot': 'Three men hammer on an anvil and pass a bottle of beer around.', 18 'rated': 'UNRATED', 19 'released': datetime.datetime(1893, 5, 9, 0, 0), 20 'runtime': 1, 21 'title': 'Blacksmith Scene', 22 'tomatoes': {'lastUpdated': datetime.datetime(2015, 6, 28, 18, 34, 9), 23 'viewer': {'meter': 32, 'numReviews': 184, 'rating': 3.0}}, 24 'type': 'movie', 25 'year': 1893}
É um filme de um minuto gravado em 1893 – é como um vídeo do YouTube de quase 130 anos atrás! Os dados acima são um único documento. Ele armazena dados em campos que podem ser acessados por nome, e você deve conseguir ver que o campo
title
contém o mesmo valor que procuramos em nossa chamada para find_one
no código acima. A estrutura de cada documento em uma coleção pode ser diferente uma da outra, mas geralmente é recomendável seguir a mesma estrutura ou estrutura semelhante para todos os documentos em uma única coleção.O MongoDB é frequentemente descrito como um banco de dados JSON, mas há evidências no documento acima de que ele não armazena JSON. Um documento do MongoDB consiste em dados armazenados como todos os tipos que o JSON pode armazenar, incluindo booleanos, inteiros, flutuadores, strings, arrays e objetos (nós os chamamos de subdocumentos). No entanto, se você examinar os campos
_id
e released
, esses são tipos que o JSON não pode armazenar. Na verdade, o MongoDB armazena dados em um formato binário chamado BSON, que também inclui o tipo ObjectId
, bem como tipos nativos para números decimais, dados binários e carimbos de data/hora (que são convertidos pelo PyMongo para o tipo datetime
nativo do Python ).A coleção
movies
contém muitos dados (23539 documentos), mas apenas filmes até 2015. Um dos meus filmes favoritos, o vencedor do Oscar "Parasita", foi lançado em 2019, portanto, não está no banco de dados! Você pode corrigir essa omissão absurda com o código abaixo:1 # Insert a document for the movie 'Parasite': 2 insert_result = movies.insert_one({ 3 "title": "Parasite", 4 "year": 2020, 5 "plot": "A poor family, the Kims, con their way into becoming the servants of a rich family, the Parks. " 6 "But their easy life gets complicated when their deception is threatened with exposure.", 7 "released": datetime(2020, 2, 7, 0, 0, 0), 8 }) 9 10 # Save the inserted_id of the document you just created: 11 parasite_id = insert_result.inserted_id 12 print("_id of inserted document: {parasite_id}".format(parasite_id=parasite_id))
Se estiver inserindo mais de um documento de uma só vez, pode ser muito mais eficiente usar o método
insert_many
, que recebe uma array de documentos a serem inseridos. (Se estiver apenas carregando documentos no banco de dados a partir de arquivos JSON armazenados, dê uma olhada no mongoimportA execução do código acima insere o documento na coleção e imprime seu ID, o que é útil, mas não tem uma aparência muito boa. Você pode recuperar o documento para provar que ele foi inserido, com o seguinte código:
1 import bson # <- Put this line near the start of the file if you prefer. 2 3 # Look up the document you just created in the collection: 4 print(movies.find_one({'_id': bson.ObjectId(parasite_id)}))
O código acima procurará um único documento que corresponda à query (neste caso, ele está procurando um
_id
específico). Se quiser procurar todos os documentos que correspondem a uma query, você deve usar o método find
, que retorna um Cursor
. Um cursor carregará dados em lote, portanto, se você tentar consultar todos os dados em sua coleção, ele começará a gerar documentos imediatamente, sem carregar a coleção inteira na memória do seu computador! Você pode percorrer os documentos retornados em um cursor com um loop for
. A query a seguir deve imprimir um ou mais documentos. Se você executou o script algumas vezes, terá inserido um documento para esse filme sempre que executar o script! (Não se preocupe em limpá-los, mostrarei como fazer isso em um momento.)1 # Look up the documents you've created in the collection: 2 for doc in movies.find({"title": "Parasite"}): 3 pprint(doc)
Muitos métodos no PyMongo, como os métodos find, esperam uma query do MongoDB como entrada. As queries do MongoDB, diferentemente do SQL, são fornecidas como estruturas de dados, não como string. O tipo mais simples de correspondências é como os acima:
{ 'key': 'value' }
em que documentos contendo o campo especificado pelo key
são retornados se o value
fornecido for o mesmo que o valor desse documento para key
. A linguagem de query do MongoDB é muito completa e eficiente, permitindo fazer correspondências com base em diferentes critérios em vários campos. A query abaixo corresponde a todos os filmes produzidos antes de 1920 com "Romance" como um dos valores de gênero:1 { 2 'year': { 3 '$lt': 1920 4 }, 5 'genres': 'Romance' 6 }
Queries e agregações ainda mais complexas são possíveis com as Agregações do MongoDB, acessadas com o método
aggregate
do PyMongo - mas esse é um tópico para uma publicação posterior de início rápido.Cometi um erro grave! O documento que você está inserindo para "Parasita" tem um erro. Embora "Parasita" tenha sido lançado em 2020, na verdade é um filme de 2019. Felizmente para nós, o MongoDB permite que você atualize documentos na coleção. Na verdade, a capacidade de atualizar atomicamente partes de um documento sem ter que atualizar um novo documento inteiro é uma funcionalidade fundamental do MongoDB!
Aqui está um código que procurará o documento que você inseriu e atualizará o campo
year
para 2019:1 # Update the document with the correct year: 2 update_result = movies.update_one({ '_id': parasite_id }, { 3 '$set': {"year": 2019} 4 }) 5 6 # Print out the updated record to make sure it's correct: 7 pprint(movies.find_one({'_id': ObjectId(parasite_id)}))
Conforme mencionado acima, você provavelmente já inseriu muitos documentos para esse filme, portanto, pode ser mais apropriado procurar todos eles e alterar o valor
year
de uma só vez. O código para isso é o seguinte:1 # Update *all* the Parasite movie docs to the correct year: 2 update_result = movies.update_many({"title": "Parasite"}, {"$set": {"year": 2019}})
Agora é hora de limpar! O código a seguir excluirá todos os documentos correspondentes da coleção - usando a mesma query ampla de antes - todos os documentos com
title
de "Parasita":1 movies.delete_many( 2 {"title": "Parasite",} 3 )
Mais uma vez, o PyMongo tem um método
delete_one
equivalente que excluirá apenas o primeiro documento correspondente que o banco de dados encontrar, em vez de excluir todos os documentos correspondentes.Curtiu este guia de início rápido? Quer saber mais? Temos um ótimo curso da MongoDB University que você vai adorar!
Se isso não for para você, temos muitos outros cursos que abrangem todos os aspectos de hospedagem e desenvolvimento com o MongoDB.
Esse início rápido cobriu apenas uma pequena parte da funcionalidade do PyMongo e do MongoDB, embora eu fale mais sobre isso nos próximos inícios rápidos do Python! Felizmente, a documentação do MongoDB e do uso do Python com o MongoDB é muito boa. Sugiro que você marque o seguinte para uma leitura divertida:
- A documentação do PyMongo fornece documentação completa descrevendo como usar o PyMongo com seu MongoDB cluster, incluindo documentação de referência abrangente sobre a classe
Collection
que foi usada extensivamente neste início rápido. - A documentação do documento de query do MongoDB detalha todo o poder disponível para consultar as coleções do MongoDB.