Python

Boas Práticas de MongoDB com Python: pymongo, Motor Assíncrono e Aggregation para Times Ágeis

18 min de leitura

Boas Práticas de MongoDB com Python: pymongo, Motor Assíncrono e Aggregation para Times Ágeis

Introdução ao MongoDB e PyMongo MongoDB é um banco de dados NoSQL orientado a documentos que armazena dados em formato JSON (ou BSON — Binary JSON). Diferentemente de bancos relacionais tradicionais, MongoDB oferece flexibilidade estrutural, permitindo que documentos na mesma coleção tenham esquemas diferentes. Python, através da biblioteca PyMongo, fornece um driver oficial para interagir com o MongoDB de forma simples e intuitiva. PyMongo é a biblioteca padrão para conectar aplicações Python ao MongoDB. Ela abstrai a complexidade do protocolo de comunicação e oferece uma API Pythônica para realizar operações CRUD (Create, Read, Update, Delete), gerenciar índices e executar consultas complexas. Antes de avançarmos para operações assíncronas e agregações, é fundamental compreender como estabelecer conexões básicas e manipular documentos. Instalação e Configuração Básica Para começar, instale o PyMongo via pip: Agora, vamos criar uma conexão simples com o MongoDB: Neste exemplo, criamos uma conexão com o MongoDB, acessamos um banco chamado e a coleção . A operação insere um único

<h2>Introdução ao MongoDB e PyMongo</h2>

<p>MongoDB é um banco de dados NoSQL orientado a documentos que armazena dados em formato JSON (ou BSON — Binary JSON). Diferentemente de bancos relacionais tradicionais, MongoDB oferece flexibilidade estrutural, permitindo que documentos na mesma coleção tenham esquemas diferentes. Python, através da biblioteca <strong>PyMongo</strong>, fornece um driver oficial para interagir com o MongoDB de forma simples e intuitiva.</p>

<p>PyMongo é a biblioteca padrão para conectar aplicações Python ao MongoDB. Ela abstrai a complexidade do protocolo de comunicação e oferece uma API Pythônica para realizar operações CRUD (Create, Read, Update, Delete), gerenciar índices e executar consultas complexas. Antes de avançarmos para operações assíncronas e agregações, é fundamental compreender como estabelecer conexões básicas e manipular documentos.</p>

<h3>Instalação e Configuração Básica</h3>

<p>Para começar, instale o PyMongo via pip:</p>

<pre><code class="language-bash">pip install pymongo</code></pre>

<p>Agora, vamos criar uma conexão simples com o MongoDB:</p>

<pre><code class="language-python">from pymongo import MongoClient

from datetime import datetime

Conectar ao servidor MongoDB local

client = MongoClient(&#039;mongodb://localhost:27017/&#039;)

Acessar um banco de dados

db = client[&#039;minha_aplicacao&#039;]

Acessar uma coleção

usuarios = db[&#039;usuarios&#039;]

Inserir um documento

documento = {

&#039;nome&#039;: &#039;João Silva&#039;,

&#039;email&#039;: &#039;joao@example.com&#039;,

&#039;idade&#039;: 28,

&#039;criado_em&#039;: datetime.now()

}

resultado = usuarios.insert_one(documento)

print(f&quot;ID inserido: {resultado.inserted_id}&quot;)</code></pre>

<p>Neste exemplo, criamos uma conexão com o MongoDB, acessamos um banco chamado <code>minha_aplicacao</code> e a coleção <code>usuarios</code>. A operação <code>insert_one()</code> insere um único documento e retorna um objeto com o ID gerado automaticamente pelo MongoDB.</p>

<h3>Operações CRUD Essenciais</h3>

<p>As operações CRUD são fundamentais. Vamos explorar cada uma:</p>

<pre><code class="language-python">from pymongo import MongoClient

from datetime import datetime

client = MongoClient(&#039;mongodb://localhost:27017/&#039;)

db = client[&#039;minha_aplicacao&#039;]

usuarios = db[&#039;usuarios&#039;]

CREATE - Inserir múltiplos documentos

novos_usuarios = [

{&#039;nome&#039;: &#039;Maria&#039;, &#039;email&#039;: &#039;maria@example.com&#039;, &#039;idade&#039;: 25},

{&#039;nome&#039;: &#039;Pedro&#039;, &#039;email&#039;: &#039;pedro@example.com&#039;, &#039;idade&#039;: 30},

{&#039;nome&#039;: &#039;Ana&#039;, &#039;email&#039;: &#039;ana@example.com&#039;, &#039;idade&#039;: 27}

]

resultado = usuarios.insert_many(novos_usuarios)

print(f&quot;IDs inseridos: {resultado.inserted_ids}&quot;)

READ - Buscar um documento

usuario = usuarios.find_one({&#039;nome&#039;: &#039;Maria&#039;})

print(f&quot;Usuário encontrado: {usuario[&#039;email&#039;]}&quot;)

READ - Buscar múltiplos documentos

usuarios_maiores_26 = usuarios.find({&#039;idade&#039;: {&#039;$gte&#039;: 26}})

for user in usuarios_maiores_26:

print(f&quot;{user[&#039;nome&#039;]} tem {user[&#039;idade&#039;]} anos&quot;)

UPDATE - Atualizar um documento

usuarios.update_one(

{&#039;nome&#039;: &#039;Maria&#039;},

{&#039;$set&#039;: {&#039;idade&#039;: 26, &#039;atualizado_em&#039;: datetime.now()}}

)

UPDATE - Atualizar múltiplos documentos

usuarios.update_many(

{&#039;idade&#039;: {&#039;$lt&#039;: 28}},

{&#039;$inc&#039;: {&#039;idade&#039;: 1}} # Incrementa a idade em 1

)

DELETE - Deletar um documento

usuarios.delete_one({&#039;nome&#039;: &#039;Pedro&#039;})

DELETE - Deletar múltiplos documentos

usuarios.delete_many({&#039;idade&#039;: {&#039;$lt&#039;: 25}})</code></pre>

<p>Compreender esses operadores MongoDB (<code>$gte</code>, <code>$set</code>, <code>$inc</code>) é crucial. Eles representam a linguagem de consulta do MongoDB e permitem operações complexas de forma declarativa.</p>

<h2>Motor: Programação Assíncrona com MongoDB</h2>

<p>Quando sua aplicação precisa lidar com múltiplas conexões simultâneas (servidores web, APIs), as operações síncronas no PyMongo podem se tornar gargalos. <strong>Motor</strong> é uma biblioteca que torna o PyMongo totalmente assíncrono, permitindo que sua aplicação não bloqueie durante operações de banco de dados.</p>

<p>Motor funciona como um wrapper assíncrono do PyMongo, mantendo a mesma API, mas retornando corrotinas que devem ser aguardadas com <code>await</code>. Isso é particularmente útil em frameworks como FastAPI, Quart e aiohttp, que também são assíncronos por natureza.</p>

<h3>Instalação e Conceitos Fundamentais</h3>

<p>Instale o Motor:</p>

<pre><code class="language-bash">pip install motor</code></pre>

<p>Antes de escrever código, entenda que o Motor utiliza <code>async/await</code>, o padrão de programação assíncrona do Python moderno. Quando você aguarda uma operação assíncrona, a thread é liberada para processar outras requisições, maximizando a utilização de recursos.</p>

<pre><code class="language-python">import asyncio

from motor.motor_asyncio import AsyncClient

from datetime import datetime

async def main():

Conectar ao MongoDB usando Motor

client = AsyncClient(&#039;mongodb://localhost:27017/&#039;)

db = client[&#039;minha_aplicacao&#039;]

usuarios = db[&#039;usuarios&#039;]

Inserir um documento de forma assíncrona

resultado = await usuarios.insert_one({

&#039;nome&#039;: &#039;Lucas&#039;,

&#039;email&#039;: &#039;lucas@example.com&#039;,

&#039;idade&#039;: 24

})

print(f&quot;Documento inserido com ID: {resultado.inserted_id}&quot;)

Buscar um documento

usuario = await usuarios.find_one({&#039;nome&#039;: &#039;Lucas&#039;})

print(f&quot;Usuário: {usuario}&quot;)

Buscar múltiplos documentos de forma assíncrona

cursor = usuarios.find({&#039;idade&#039;: {&#039;$gte&#039;: 20}})

async for user in cursor:

print(f&quot;{user[&#039;nome&#039;]}: {user[&#039;idade&#039;]} anos&quot;)

Fechar a conexão

client.close()

Executar a corrotina

asyncio.run(main())</code></pre>

<p>A diferença fundamental é que cada operação retorna uma corrotina que deve ser aguardada com <code>await</code>. Isso permite que o event loop do Python processe outras tarefas enquanto o banco de dados processa a requisição.</p>

<h3>Integrando Motor com FastAPI</h3>

<p>Motor brilha quando integrado com frameworks web assíncronos. Aqui está um exemplo com FastAPI:</p>

<pre><code class="language-python">from fastapi import FastAPI, HTTPException

from motor.motor_asyncio import AsyncClient

from pydantic import BaseModel

from typing import Optional

from bson import ObjectId

app = FastAPI()

Configuração do banco de dados

MONGODB_URL = &quot;mongodb://localhost:27017&quot;

client = AsyncClient(MONGODB_URL)

db = client[&#039;minha_aplicacao&#039;]

Fechar a conexão ao desligar a aplicação

@app.on_event(&quot;shutdown&quot;)

async def shutdown_db():

client.close()

Modelo Pydantic para validação

class Usuario(BaseModel):

nome: str

email: str

idade: int

class UsuarioResponse(Usuario):

id: str

class Config:

from_attributes = True

@app.post(&quot;/usuarios/&quot;)

async def criar_usuario(usuario: Usuario):

collection = db[&#039;usuarios&#039;]

resultado = await collection.insert_one(usuario.dict())

return {&quot;id&quot;: str(resultado.inserted_id), **usuario.dict()}

@app.get(&quot;/usuarios/{usuario_id}&quot;)

async def obter_usuario(usuario_id: str):

collection = db[&#039;usuarios&#039;]

try:

documento = await collection.find_one({&quot;_id&quot;: ObjectId(usuario_id)})

if not documento:

raise HTTPException(status_code=404, detail=&quot;Usuário não encontrado&quot;)

documento[&#039;id&#039;] = str(documento[&#039;_id&#039;])

return documento

except Exception as e:

raise HTTPException(status_code=400, detail=f&quot;ID inválido: {str(e)}&quot;)

@app.get(&quot;/usuarios/&quot;)

async def listar_usuarios(skip: int = 0, limit: int = 10):

collection = db[&#039;usuarios&#039;]

cursor = collection.find().skip(skip).limit(limit)

usuarios = []

async for doc in cursor:

doc[&#039;id&#039;] = str(doc[&#039;_id&#039;])

usuarios.append(doc)

return usuarios

@app.put(&quot;/usuarios/{usuario_id}&quot;)

async def atualizar_usuario(usuario_id: str, usuario: Usuario):

collection = db[&#039;usuarios&#039;]

try:

resultado = await collection.update_one(

{&quot;_id&quot;: ObjectId(usuario_id)},

{&quot;$set&quot;: usuario.dict()}

)

if resultado.matched_count == 0:

raise HTTPException(status_code=404, detail=&quot;Usuário não encontrado&quot;)

return {&quot;mensagem&quot;: &quot;Usuário atualizado com sucesso&quot;}

except Exception as e:

raise HTTPException(status_code=400, detail=f&quot;Erro: {str(e)}&quot;)

@app.delete(&quot;/usuarios/{usuario_id}&quot;)

async def deletar_usuario(usuario_id: str):

collection = db[&#039;usuarios&#039;]

try:

resultado = await collection.delete_one({&quot;_id&quot;: ObjectId(usuario_id)})

if resultado.deleted_count == 0:

raise HTTPException(status_code=404, detail=&quot;Usuário não encontrado&quot;)

return {&quot;mensagem&quot;: &quot;Usuário deletado com sucesso&quot;}

except Exception as e:

raise HTTPException(status_code=400, detail=f&quot;Erro: {str(e)}&quot;)</code></pre>

<p>Este exemplo demonstra como Motor integra perfeitamente com FastAPI, mantendo a aplicação responsiva mesmo sob carga elevada. Cada requisição HTTP é processada de forma assíncrona, e enquanto aguarda a resposta do banco de dados, o event loop pode processar outras requisições.</p>

<h2>Agregação: Processamento Avançado de Dados</h2>

<p>A agregação no MongoDB é um framework poderoso para transformar, filtrar e processar documentos no próprio servidor. Diferentemente de buscas simples, agregações permitem operações complexas como agrupamento, projeção, ordenação e cálculos, tudo de forma eficiente no lado do servidor. Isso reduz drasticamente a quantidade de dados transferidos para a aplicação.</p>

<h3>Conceitos de Pipeline de Agregação</h3>

<p>Uma agregação no MongoDB funciona como um pipeline: documentos passam por uma série de estágios (<code>stages</code>), cada um transformando os dados até obter o resultado final. Os estágios mais comuns são:</p>

<ul>

<li><strong>$match</strong>: Filtra documentos (equivalente a WHERE no SQL)</li>

<li><strong>$group</strong>: Agrupa documentos por um campo específico</li>

<li><strong>$project</strong>: Seleciona/renomeia campos</li>

<li><strong>$sort</strong>: Ordena documentos</li>

<li><strong>$limit</strong>: Limita o número de documentos</li>

<li><strong>$lookup</strong>: Join com outra coleção</li>

<li><strong>$unwind</strong>: Desconstrói arrays em documentos separados</li>

<li><strong>$addFields</strong>: Adiciona novos campos calculados</li>

</ul>

<p>Vamos ilustrar com um exemplo prático:</p>

<pre><code class="language-python">from pymongo import MongoClient

from datetime import datetime, timedelta

client = MongoClient(&#039;mongodb://localhost:27017/&#039;)

db = client[&#039;loja&#039;]

vendas = db[&#039;vendas&#039;]

Inserir dados de exemplo

vendas.insert_many([

{

&#039;data&#039;: datetime.now() - timedelta(days=10),

&#039;vendedor&#039;: &#039;João&#039;,

&#039;produto&#039;: &#039;Notebook&#039;,

&#039;quantidade&#039;: 2,

&#039;preco_unitario&#039;: 3000

},

{

&#039;data&#039;: datetime.now() - timedelta(days=8),

&#039;vendedor&#039;: &#039;Maria&#039;,

&#039;produto&#039;: &#039;Mouse&#039;,

&#039;quantidade&#039;: 10,

&#039;preco_unitario&#039;: 50

},

{

&#039;data&#039;: datetime.now() - timedelta(days=5),

&#039;vendedor&#039;: &#039;João&#039;,

&#039;produto&#039;: &#039;Teclado&#039;,

&#039;quantidade&#039;: 5,

&#039;preco_unitario&#039;: 150

},

{

&#039;data&#039;: datetime.now() - timedelta(days=3),

&#039;vendedor&#039;: &#039;Maria&#039;,

&#039;produto&#039;: &#039;Monitor&#039;,

&#039;quantidade&#039;: 1,

&#039;preco_unitario&#039;: 1200

},

])

Pipeline de agregação: Total de vendas por vendedor

pipeline = [

{

&#039;$group&#039;: {

&#039;_id&#039;: &#039;$vendedor&#039;,

&#039;total_vendido&#039;: {

&#039;$sum&#039;: {&#039;$multiply&#039;: [&#039;$quantidade&#039;, &#039;$preco_unitario&#039;]}

},

&#039;quantidade_produtos&#039;: {&#039;$sum&#039;: &#039;$quantidade&#039;}

}

},

{

&#039;$sort&#039;: {&#039;total_vendido&#039;: -1}

}

]

resultado = list(vendas.aggregate(pipeline))

for doc in resultado:

print(f&quot;Vendedor: {doc[&#039;_id&#039;]}, Total: R$ {doc[&#039;total_vendido&#039;]}, Quantidade: {doc[&#039;quantidade_produtos&#039;]}&quot;)</code></pre>

<p>Este pipeline primeiro agrupa as vendas por vendedor, calculando o total de vendas e a quantidade total de produtos, depois ordena pelo total de vendas em ordem decrescente.</p>

<h3>Agregações Complexas com Lookups e Unwinding</h3>

<p>Para casos mais avançados, combinamos múltiplos estágios:</p>

<pre><code class="language-python">from pymongo import MongoClient

client = MongoClient(&#039;mongodb://localhost:27017/&#039;)

db = client[&#039;escola&#039;]

Criar coleções de exemplo

alunos = db[&#039;alunos&#039;]

notas = db[&#039;notas&#039;]

Limpar dados anteriores

alunos.delete_many({})

notas.delete_many({})

Inserir alunos

alunos.insert_many([

{&#039;_id&#039;: 1, &#039;nome&#039;: &#039;Alice&#039;},

{&#039;_id&#039;: 2, &#039;nome&#039;: &#039;Bob&#039;},

{&#039;_id&#039;: 3, &#039;nome&#039;: &#039;Carlos&#039;}

])

Inserir notas (referenciando alunos)

notas.insert_many([

{&#039;aluno_id&#039;: 1, &#039;materia&#039;: &#039;Matemática&#039;, &#039;nota&#039;: 8.5},

{&#039;aluno_id&#039;: 1, &#039;materia&#039;: &#039;Português&#039;, &#039;nota&#039;: 9.0},

{&#039;aluno_id&#039;: 2, &#039;materia&#039;: &#039;Matemática&#039;, &#039;nota&#039;: 7.0},

{&#039;aluno_id&#039;: 2, &#039;materia&#039;: &#039;Português&#039;, &#039;nota&#039;: 8.0},

{&#039;aluno_id&#039;: 3, &#039;materia&#039;: &#039;Matemática&#039;, &#039;nota&#039;: 9.5},

{&#039;aluno_id&#039;: 3, &#039;materia&#039;: &#039;Português&#039;, &#039;nota&#039;: 7.5},

])

Pipeline: Média de notas por aluno

pipeline = [

{

&#039;$group&#039;: {

&#039;_id&#039;: &#039;$aluno_id&#039;,

&#039;media&#039;: {&#039;$avg&#039;: &#039;$nota&#039;},

&#039;notas_obtidas&#039;: {&#039;$push&#039;: &#039;$nota&#039;}

}

},

{

&#039;$lookup&#039;: {

&#039;from&#039;: &#039;alunos&#039;,

&#039;localField&#039;: &#039;_id&#039;,

&#039;foreignField&#039;: &#039;_id&#039;,

&#039;as&#039;: &#039;info_aluno&#039;

}

},

{

&#039;$unwind&#039;: &#039;$info_aluno&#039;

},

{

&#039;$project&#039;: {

&#039;_id&#039;: 0,

&#039;nome&#039;: &#039;$info_aluno.nome&#039;,

&#039;media&#039;: {&#039;$round&#039;: [&#039;$media&#039;, 2]},

&#039;total_notas&#039;: {&#039;$size&#039;: &#039;$notas_obtidas&#039;},

&#039;situacao&#039;: {

&#039;$cond&#039;: [

{&#039;$gte&#039;: [&#039;$media&#039;, 7]},

&#039;Aprovado&#039;,

&#039;Reprovado&#039;

]

}

}

},

{

&#039;$sort&#039;: {&#039;media&#039;: -1}

}

]

resultado = list(notas.aggregate(pipeline))

for doc in resultado:

print(f&quot;{doc[&#039;nome&#039;]}: Média {doc[&#039;media&#039;]} - {doc[&#039;situacao&#039;]} ({doc[&#039;total_notas&#039;]} notas)&quot;)</code></pre>

<p>Neste exemplo complexo, fazemos:</p>

<ol>

<li>Agrupamos notas por aluno, calculando a média</li>

<li>Fazemos um <code>lookup</code> (join) com a coleção de alunos</li>

<li>Desconstruímos o array de alunos com <code>$unwind</code></li>

<li>Projetamos campos customizados com lógica condicional (<code>$cond</code>)</li>

<li>Ordenamos pelo resultado final</li>

</ol>

<h3>Agregação Assíncrona com Motor</h3>

<p>Motor também oferece suporte a agregações assíncronas:</p>

<pre><code class="language-python">import asyncio

from motor.motor_asyncio import AsyncClient

async def agregacao_assincrona():

client = AsyncClient(&#039;mongodb://localhost:27017/&#039;)

db = client[&#039;vendas_online&#039;]

pedidos = db[&#039;pedidos&#039;]

Inserir dados de exemplo

await pedidos.insert_many([

{&#039;cliente&#039;: &#039;Alice&#039;, &#039;valor&#039;: 150.00, &#039;status&#039;: &#039;entregue&#039;},

{&#039;cliente&#039;: &#039;Bob&#039;, &#039;valor&#039;: 320.00, &#039;status&#039;: &#039;entregue&#039;},

{&#039;cliente&#039;: &#039;Alice&#039;, &#039;valor&#039;: 80.00, &#039;status&#039;: &#039;pendente&#039;},

{&#039;cliente&#039;: &#039;Carlos&#039;, &#039;valor&#039;: 450.00, &#039;status&#039;: &#039;entregue&#039;},

{&#039;cliente&#039;: &#039;Bob&#039;, &#039;valor&#039;: 200.00, &#039;status&#039;: &#039;cancelado&#039;},

])

Pipeline de agregação

pipeline = [

{

&#039;$match&#039;: {&#039;status&#039;: &#039;entregue&#039;}

},

{

&#039;$group&#039;: {

&#039;_id&#039;: &#039;$cliente&#039;,

&#039;total_gasto&#039;: {&#039;$sum&#039;: &#039;$valor&#039;},

&#039;quantidade_pedidos&#039;: {&#039;$sum&#039;: 1}

}

},

{

&#039;$sort&#039;: {&#039;total_gasto&#039;: -1}

}

]

Executar agregação de forma assíncrona

cursor = pedidos.aggregate(pipeline)

print(&quot;=== Clientes com mais compras entregues ===&quot;)

async for doc in cursor:

print(f&quot;{doc[&#039;_id&#039;]}: R$ {doc[&#039;total_gasto&#039;]:.2f} ({doc[&#039;quantidade_pedidos&#039;]} pedidos)&quot;)

client.close()

asyncio.run(agregacao_assincrona())</code></pre>

<p>Este exemplo demonstra como usar agregações com Motor, permitindo processamento eficiente de grandes volumes de dados sem bloquear a aplicação.</p>

<h3>Dicas de Performance em Agregações</h3>

<p>Agregações são poderosas, mas devem ser otimizadas. Use índices nos campos usados em <code>$match</code> para melhorar drasticamente a performance. Posicione <code>$match</code> o mais cedo possível no pipeline, reduzindo o volume de dados processados nos estágios subsequentes. Evite <code>$lookup</code> em coleções muito grandes, pois isso tem custo computacional elevado.</p>

<pre><code class="language-python"># Exemplo de criação de índices

vendas = db[&#039;vendas&#039;]

vendas.create_index(&#039;vendedor&#039;) # Índice simples

vendas.create_index([(&#039;data&#039;, -1), (&#039;vendedor&#039;, 1)]) # Índice composto</code></pre>

<h2>Conclusão</h2>

<p>Nesta aula aprofundada, você aprendeu que <strong>MongoDB com Python oferece flexibilidade estrutural aliada a simplicidade de uso</strong>, seja através do PyMongo para aplicações síncronas ou Motor para sistemas de alta concorrência. A escolha entre PyMongo e Motor depende da arquitetura de sua aplicação: se você está construindo APIs assíncronas modernas com FastAPI, Quart ou aiohttp, Motor é a solução natural; caso contrário, PyMongo oferece simplicidade sem comprometer funcionalidade.</p>

<p>Em segundo lugar, <strong>agregações são o coração do processamento avançado no MongoDB</strong>, permitindo que você realize operações complexas no servidor em vez de trazer dados brutos para a aplicação. Dominar pipelines de agregação transforma-o de um usuário básico a um profissional capaz de extrair insights de dados em tempo real, otimizando performance e reduzindo consumo de banda.</p>

<p>Por fim, <strong>a combinação de Motor + FastAPI + Agregações cria aplicações escaláveis e eficientes</strong>, capazes de servir centenas de requisições simultâneas sem degradação de performance. Pratique construindo pequenos projetos, domine os operadores de agregação, e você terá domínio completo dessa stack moderna e poderosa.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://pymongo.readthedocs.io/en/stable/" target="_blank" rel="noopener noreferrer">Documentação Oficial do PyMongo</a></li>

<li><a href="https://motor.readthedocs.io/" target="_blank" rel="noopener noreferrer">Documentação do Motor - Async Driver para MongoDB</a></li>

<li><a href="https://docs.mongodb.com/manual/reference/operator/aggregation/" target="_blank" rel="noopener noreferrer">MongoDB Aggregation Pipeline Documentation</a></li>

<li><a href="https://fastapi.tiangolo.com/tutorial/sql-databases/" target="_blank" rel="noopener noreferrer">FastAPI com Banco de Dados</a></li>

<li><a href="https://realpython.com/motor-motor-asyncio-mongodb-python/" target="_blank" rel="noopener noreferrer">Real Python - Motor and Asyncio</a></li>

</ul>

<p>&lt;!-- FIM --&gt;</p>

Comentários

Mais em Python

Boas Práticas de Generators e yield em Python: Lazy Evaluation e Pipelines de Dados para Times Ágeis
Boas Práticas de Generators e yield em Python: Lazy Evaluation e Pipelines de Dados para Times Ágeis

Entendendo Generators: O Que Realmente São Um generator em Python é uma funçã...

Ruff, Black e isort em Python: Linting e Formatação Automatizada: Do Básico ao Avançado
Ruff, Black e isort em Python: Linting e Formatação Automatizada: Do Básico ao Avançado

Introdução: Por que Qualidade de Código Importa Quando você começa a programa...

Guia Completo de Listas, Tuplas, Sets e Dicionários em Python na Prática
Guia Completo de Listas, Tuplas, Sets e Dicionários em Python na Prática

Estruturas de Dados em Python: Listas, Tuplas, Sets e Dicionários Python ofer...