A Voyage AI se une ao MongoDB para impulsionar aplicativos de AI mais precisos e confiáveis no Atlas.

Explore o novo chatbot do Developer Center! O MongoDB AI chatbot pode ser acessado na parte superior da sua navegação para responder a todas as suas perguntas sobre o MongoDB .

Introdução ao MongoDB e Sanic

Aaron Bassett5 min read • Published Feb 05, 2022 • Updated Jul 12, 2024
Facebook Icontwitter iconlinkedin icon
Classifique este início rápido
star-empty
star-empty
star-empty
star-empty
star-empty
QuickStart Python Logo
Sanic is a Python 3.6+ async web server and web framework that's written to go fast. The project's goal is to provide a simple way to get up and running a highly performant HTTP server that is easy to build, to expand, and ultimately to scale.
Unfortunately, because of its name and dubious choices in ASCII art, Sanic wasn't seen by some as a serious framework, but it has matured. It is worth considering if you need a fast, async, Python framework.
Neste início rápido, criaremos um aplicativo CRUD (Criar, Ler, Atualizar, Excluir) mostrando como você pode integrar o MongoDB com seus projetos Sanic.

Pré-requisitos

  • Python 3.9.0
  • Um MongoDB Atlas cluster. Siga o guia "Introdução ao Atlas" para criar sua conta e o MongoDB cluster. Anote seu nome de usuário, senha e string de conexão, porque você precisará deles depois.

Executando o exemplo

Para começar, você deve clonar o código de exemplo do GitHub.
1git clone git@github.com:mongodb-developer/mongodb-with-sanic.git
You will need to install a few dependencies: Sanic, Motor, etc. I always recommend that you install all Python dependencies in a virtualenv for the project. Before running pip, ensure your virtualenv is active.
1cd mongodb-with-sanic
2pip install -r requirements.txt
Pode levar alguns minutos para baixar e instalar suas dependências. Isso é normal, principalmente se tiver algum pacote que você não instalou antes.
Depois de instalar as dependências, você precisará criar uma variável de ambiente para sua string de conexão do MongoDB.
1export MONGODB_URL="mongodb+srv://<username>:<password>@<url>/<db>?retryWrites=true&w=majority"
Lembre-se de que sempre que iniciar uma nova sessão de terminal, será necessário definir essa variável de ambiente de novo. Eu uso direnv para facilitar esse processo.
The final step is to start your Sanic server.
1python app.py
Screenshot of terminal running Sanic
Once the application has started, you can view it in your browser at http://127.0.0.1:8000/. There won't be much to see at the moment as you do not have any data! We'll look at each of the end-points a little later in the tutorial, but if you would like to create some data now to test, you need to send a POST request with a JSON body to the local URL.
1curl -X "POST" "http://localhost:8000/" \
2 -H 'Accept: application/json' \
3 -H 'Content-Type: application/json; charset=utf-8' \
4 -d '{
5 "name": "Jane Doe",
6 "email": "jdoe@example.com",
7 "gpa": "3.9"
8 }'
Try creating a few students via these POST requests, and then refresh your browser.

Criação do aplicativo

Todo o código do aplicativo de exemplo está em app.py. Vou dividi-lo em seções e explicar o que cada uma está fazendo.

Setting Up Our App and MongoDB Connection

We're going to use the sanic-motor package to wrap our motor client for ease of use. So, we need to provide a couple of settings when creating our Sanic app.
1app = Sanic(__name__)
2
3settings = dict(
4 MOTOR_URI=os.environ["MONGODB_URL"],
5 LOGO=None,
6)
7app.config.update(settings)
8
9BaseModel.init_app(app)
10
11
12class Student(BaseModel):
13 __coll__ = "students"
Sanic-motor's models are unlikely to be very similar to any other database models you have used before. They do not describe the schema, for example. Instead, we only specify the collection name.

Rotas de aplicativos

Nosso aplicativo tem cinco rotas:
  • POST / - creates a new student.
  • GET / - view a list of all students.
  • GET /{id} - view a single student.
  • PUT /{id} - update a student.
  • DELETE /{id} - delete a student.

Criar rota do aluno

1@app.route("/", methods=["POST"])
2async def create_student(request):
3 student = request.json
4 student["_id"] = str(ObjectId())
5
6 new_student = await Student.insert_one(student)
7 created_student = await Student.find_one(
8 {"_id": new_student.inserted_id}, as_raw=True
9 )
10
11 return json_response(created_student)
Note how I am converting the ObjectId to a string before assigning it as the _id. MongoDB stores data as BSON. However, we are encoding and decoding our data as JSON strings. BSON has support for additional non-JSON-native data types, including ObjectId. JSON does not. Because of this, for simplicity, we convert ObjectIds to strings before storing them.
The create_student route receives the new student data as a JSON string in a POST request. Sanic will automatically convert this JSON string back into a Python dictionary which we can then pass to the sanic-motor wrapper.
The insert_one method response includes the _id of the newly created student. After we insert the student into our collection, we use the inserted_id to find the correct document and return it in the json_response.
sanic-motor returns the relevant model objects from any find method, including find_one. To override this behaviour, we specify as_raw=True.
Ler rotas
The application has two read routes: one for viewing all students, and the other for viewing an individual student.
1@app.route("/", methods=["GET"])
2async def list_students(request):
3 students = await Student.find(as_raw=True)
4 return json_response(students.objects)
In our example code, we are not placing any limits on the number of students returned. In a real application, you should use sanic-motor's page and per_page arguments to paginate the number of students returned.
1@app.route("/<id>", methods=["GET"])
2async def show_student(request, id):
3 if (student := await Student.find_one({"_id": id}, as_raw=True)) is not None:
4 return json_response(student)
5
6 raise NotFound(f"Student {id} not found")
The student detail route has a path parameter of id, which Sanic passes as an argument to the show_student function. We use the id to attempt to find the corresponding student in the database. The conditional in this section is using an assignment expression, a recent addition to Python (introduced in version 3.8) and often referred to by the incredibly cute sobriquet "walrus operator."
If a document with the specified id does not exist, we raise a NotFound exception which will respond to the request with a 404 response.
Atualizar rota
1@app.route("/<id>", methods=["PUT"])
2async def update_student(request, id):
3 student = request.json
4 update_result = await Student.update_one({"_id": id}, {"$set": student})
5
6 if update_result.modified_count == 1:
7 if (
8 updated_student := await Student.find_one({"_id": id}, as_raw=True)
9 ) is not None:
10 return json_response(updated_student)
11
12 if (
13 existing_student := await Student.find_one({"_id": id}, as_raw=True)
14 ) is not None:
15 return json_response(existing_student)
16
17 raise NotFound(f"Student {id} not found")
The update_student route is like a combination of the create_student and the show_student routes. It receives the id of the document to update as well as the new data in the JSON body.
We attempt to $set the new values in the correct document with update_one, and then check to see if it correctly modified a single document. If it did, then we find that document that was just updated and return it.
If the modified_count is not equal to one, we still check to see if there is a document matching the id. A modified_count of zero could mean that there is no document with that id. It could also mean that the document does exist but it did not require updating as the current values are the same as those supplied in the PUT request.
It is only after that final find fail when we raise a 404 Not Found exception.
Excluir rota
1@app.route("/<id>", methods=["DELETE"])
2async def delete_student(request, id):
3 delete_result = await Student.delete_one({"_id": id})
4
5 if delete_result.deleted_count == 1:
6 return json_response({}, status=204)
7
8 raise NotFound(f"Student {id} not found")
Our final route is delete_student. Again, because this is acting upon a single document, we have to supply an id in the URL. If we find a matching document and successfully delete it, then we return an HTTP status of 204 or "No Content." In this case, we do not return a document as we've already deleted it! However, if we cannot find a student with the specified id, then instead, we return a 404.

Encerrando

I hope you have found this introduction to Sanic with MongoDB useful. If you would like to find out more about Sanic, please see their documentation. Unfortunately, documentation for sanic-motor is entirely lacking at this time. But, it is a relatively thin wrapper around the MongoDB Motor driver—which is well documented—so do not let that discourage you.
To see how you can integrate MongoDB with other async frameworks, check out some of the other Python posts on the MongoDB developer portal.
Em caso de dúvidas, acesse nosso website da comunidade de desenvolvedores, no qual os engenheiros do MongoDB e a MongoDB Community ajudarão você a colocar em prática sua próxima grande ideia com o MongoDB.

Facebook Icontwitter iconlinkedin icon
Classifique este início rápido
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Tutorial

Crie aplicativos inteligentes com o Atlas Vector Search e o Google Vertex AI


Sep 18, 2024 | 4 min read
Tutorial

Como usar os módulos de incorporações e reclassificação do Cohere com o MongoDB Atlas


Mar 13, 2025 | 10 min read
Tutorial

Avaliação RAG: detectando alucinações com Patronus AI e MongoDB


Aug 15, 2024 | 11 min read
Tutorial

Autenticação do MongoDB Atlas usando contas de serviço (OAuth)


Jan 23, 2025 | 9 min read