5
respostas

[Dúvida] Dúvida main.py | get_db

Estou com o seguinte erro:

line 59, in create_product
db = get_db()
^^^^^^
NameError: name 'get_db' is not defined

Segue o meu código:

@main_bp.route('/products', methods=['POST'])
@token_required
def create_product(token):
try:
product = Product(**request.get_json())
except ValidationError as e:
return jsonify({"error": e.errors()}), 400

result = db.products.insert_one(product.model_dump())

return jsonify({"message":"Esta é a rota de criação de produto",
                "id": str(result.inserted_id)
                }), 201

Definindo o get_db dentro dessa def, como no exemplo abaixo:

def create_product(token):
db = get_db()
try:....

No postman ele tetorna como:

{
"error": "Token Expirado"
}

Quando gero um novo token, ele retorna:

line 59, in create_product
db = get_db()
^^^^^^
NameError: name 'get_db' is not defined

Poderiam me ajuda?

5 respostas

Olá Roberth! Como vai?

O erro "NameError: name 'get_db' is not defined" está ocorrendo porque a função get_db() não está definida no seu código ou não está sendo importada corretamente.

Aqui estão algumas sugestões para resolver o problema:

  1. Defina a Função get_db: Certifique-se de que a função get_db() está definida em algum lugar do seu código. Essa função geralmente é responsável por estabelecer a conexão com o banco de dados MongoDB. Um exemplo básico de como essa função pode ser definida é:

    from pymongo import MongoClient
    
    def get_db():
        client = MongoClient('mongodb://localhost:27017/')
        db = client['seu_nome_do_banco']
        return db
    
  2. Importe a Função Corretamente: Se a função get_db() estiver definida em outro arquivo, você precisa importá-la no arquivo onde está tentando usá-la. Por exemplo, se get_db() estiver em um arquivo chamado database.py, você deve importar assim:

    from database import get_db
    
  3. Verifique o Contexto de Execução: Certifique-se de que a função get_db() é chamada dentro do contexto correto, ou seja, dentro de uma função ou bloco de código onde ela está acessível.

  4. Verifique o Caminho do Banco de Dados: Caso a função esteja definida corretamente e importada, verifique se o caminho para o banco de dados MongoDB está correto e se o servidor do MongoDB está rodando.

Após verificar e corrigir esses pontos, tente executar novamente o seu código. Espero que isso ajude a resolver o erro que você está enfrentando!

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.

Continuo com o erro =(

Segue o meu init.py

from flask import Flask
from config import Config
from pymongo import MongoClient # Responsável por criar a conectividade com o banco de dados

db = None

def get_db():
client = MongoClient('mongodb://localhost:27017/')
db = client['stylesync']
return db

def create_app():
app = Flask(name)
app.config.from_object('config.Config')
app.config['SECRET_KEY'] = 'UmaSenhaSecreta'
global db # a variável foi definida fora da função create_app para que não seja criado uma nova variável e ultilize aquela para ser preenchido

try:
    client = MongoClient(app.config['MONGO_URI'])
    db = client.get_default_database()
except Exception as e:
    print(f'Erro ao realizar a conexao com o banco de dados: {e}')

from .routes.main import main_bp # Importando apenas no factory e não no módulo
app.register_blueprint(main_bp) # Dizendo para a instancia do Flask utilizar o Blueprint(main_bp)

return app

segue o meu main.py

from flask import Blueprint, jsonify, request, current_app
from app.models.user import LoginPayload
from pydantic import ValidationError
from app import db
from bson import ObjectId # converte a string para o id do Mongo
from app.models.products import *
from app.decorators import token_required
from datetime import datetime, timedelta, timezone
import jwt

request = permite pegar as informação no body via requicisão da rota login

Blueprint = Responsável por organizar todo grupo de rotas relacionadas

jsonifyS = Converte todos os dicionários python em um dicionário json

main_bp = Blueprint('main_bp', name)

Requisito Funcional: O sistema deve permitir que um usuário se autentique para obter um token

@main_bp.route('/login', methods=['POST'])
def login():
try:
raw_data = request.get_json()
# ** = desaclopa o dicionário em argumentos palavra-chave que serão atribuidos automaticamente nos atributos de classe
user_data = LoginPayload(**raw_data)
except ValidationError as e:
return jsonify({"error": e.errors()}), 400
except Exception as e:
return jsonify({"error": "Corpo da requisição inválido ou não é um JSON"})

if user_data.username == "admin" and user_data.password == "supersecret":
    token = jwt.encode(
        {
            "user_id": user_data.username,
            "exp": datetime.now(timezone.utc) + timedelta(minutes=30)
        },
        current_app.config['SECRET_KEY'],
        algorithm='HS256'
    )

    return jsonify({'access_token': token}), 200

return jsonify({"error": "Credenciais invalidas"}), 401

RF: O sistema deve permitir listagem de todos os produtos

@token_required
@main_bp.route('/products', methods=['GET'])
def get_products(token):
products_cursor = db.products.find({})
products_list = [ProductDBModel(**product).model_dump(by_alias=True, exclude_none=True) for product in products_cursor]
return jsonify(products_list)

RF: O sistema deve permitir a criação de um novo produto

@main_bp.route('/products', methods=['POST'])
@token_required
def create_product(token):
db = get_db()
try:
product = Product(**request.get_json())
except ValidationError as e:
return jsonify({"error": e.errors()}), 400

result = db.products.insert_one(product.model_dump())

return jsonify({"message":"Esta é a rota de criação de produto",
                "id": str(result.inserted_id)
                }), 201

RF: O sistema deve permitir a visualização dos detalhes de um unico produto

@main_bp.route('/products/string:product_id', methods=['GET'])
def get_product_by_id(product_id):
try:
oid = ObjectId(product_id)
except Exception as e:
return jsonify({"error":f"Erro ao transformar o {product_id} em ObjectID: {e}"})

product = db.products.find_one({'_id':oid})

if product:
    product_model = ProductDBModel(**product).model_dump(by_alias=True, exclude_none=None) 
    return jsonify(product)
else:
    return jsonify({"error":f"Produto com o id: {product_id} - Não encontrado"})

RF: O sistema deve permitir a atualização de um unico produto e produto existente

@main_bp.route('/product/int:product_id', methods=['PUT'])
def update_product(product_id):
return jsonify({"message":f"Esta é a rota de atualizacao do produto com o id {product_id}"})

RF: O sistema deve permitir a delecao de um unico produto e produto existente

@main_bp.route('/product/int:product_id', methods=['DELELE'])
def delete_product(product_id):
return jsonify({"message":f"Esta é a rota de delecao do produto com o id {product_id}"})

RF: O sistema deve permitir a importação de vendas através de um arquivo

@main_bp.route('/sales/upload', methods=['POST'])
def upload_sales(product_id):
return jsonify({"message":"Esta é a rota de upload do arquivo de vendas"})

@main_bp.route('/')
def index():
return jsonify({"message":"Bem vindo ao StyleSync"})

Uma outra dúvida: Se eu assinar o plano Ultra Lab da Alura, consigo tirar essas dúvidas ao vivo com algum instrutor?

Oi, Roberth!

O problema é que a função get_db existe no seu init.py, mas não está sendo importada no main.py. Do jeito que você explicou, no main.py você só importou a variável db, e não a função get_db, por isso o Python não encontra esse nome em tempo de execução.

Resolva fazendo o seguinte: importe explicitamente o get_db no main.py a partir do módulo app (onde ele está definido).

Ajuste seu código assim:


from app import db, get_db

Com isso, a chamada abaixo passa a funcionar corretamente:


@main_bp.route('/products', methods=['POST'])
@token_required
def create_product(token):
    db = get_db()
    try:
        product = Product(**request.get_json())
    except ValidationError as e:
        return jsonify({"error": e.errors()}), 400

    result = db.products.insert_one(product.model_dump())

    return jsonify({
        "message": "Esta é a rota de criação de produto",
        "id": str(result.inserted_id)
    }), 201

Pontos importantes:

  • get_db está definido no init.py, então ele só fica acessível se for importado explicitamente.
  • Importar apenas db não torna get_db visível no escopo do main.py.
  • O erro de Token Expirado aparece antes porque o decorator barra a execução da função; quando o token é válido, o código entra no método e o NameError é disparado.

Sobre a última dúvida, não, independente do plano que você escolha, não oferecemos mentoria particular, pois acaba sendo inviável pelo número de alunos. Mas, caso queira ter um contato mais direto com pessoas que podem te ajudar em calls recomendo que acesse o Discord da Alura que conta com uma comunidade que está sempre disposta a ajudar.

Para achar o link do Discord, acesse o Dashboard e na aba lateral esquerda procure por Comunidade.

Fico à disposição!