[Python] RuntimeError: The current Flask app is not registered with this 'SQLAlchemy' instance

Discussão em 'Python' iniciado por Stack, Junho 8, 2025.

  1. Stack

    Stack Membro Participativo

    I'm having troubles to init my app on flask. It says "Did you forget to call 'init_app', or did you create multiple 'SQLAlchemy' instances?" I call init_app as "db.init_app(app)" and as far as I look to the code I avoid to create multiple SQLAlchemy instances. I call an extensions.py just to create a SQLAlchemy instance and call it on models and on main, I don't create this instance anywhere else. here is the main.py:

    # main.py
    import os
    from flask import Flask, render_template, url_for, flash, redirect, request, Blueprint, jsonify, abort, current_app
    from werkzeug.utils import secure_filename
    from PIL import Image
    from datetime import datetime
    from config import Config
    from .extensions import db, login_manager
    from .models import Produto, DadosFormulario, User # Import User model
    from .forms import ProductForm # Assuming you have a forms.py with ProductForm
    from flask_login import login_required, current_user, login_user, logout_user # Add login_user, logout_user

    # Define the Blueprint
    main = Blueprint('main', __name__)

    # --- Authentication Routes (Add these if you don't have them yet) ---
    @main.route('/login', methods=['GET', 'POST'])
    def login():
    if current_user.is_authenticated:
    return redirect(url_for('main.profile'))
    # Assuming you have a LoginForm in forms.py
    from .forms import LoginForm # Import LoginForm here
    form = LoginForm()
    if form.validate_on_submit():
    user = User.query.filter_by(email=form.email.data).first()
    if user and user.password == form.password.data: # In a real app, use werkzeug.security.check_password_hash
    login_user(user, remember=form.remember.data)
    next_page = request.args.get('next')
    return redirect(next_page) if next_page else redirect(url_for('main.profile'))
    else:
    flash('Login Unsuccessful. Please check email and password', 'danger')
    return render_template('login.html', title='Login', form=form)

    @main.route('/logout')
    def logout():
    logout_user()
    return redirect(url_for('main.index'))

    # --- Existing Routes ---
    @main.route('/')
    def index():
    return render_template('index.html')

    @main.route('/profile')
    @login_required
    def profile():
    return render_template('profile.html', name=current_user.name)

    @main.route('/contato')
    def contato():
    return render_template('contato.html')

    @main.route('/enviar', methods=['POST'])
    def enviar():
    nome = request.form['nome']
    email = request.form['email']
    estado = request.form.get('estado')
    cidade = request.form.get('cidade')
    mensagem = request.form['mensagem']

    novo_dado = DadosFormulario(nome=nome, email=email, estado=estado, cidade=cidade, mensagem=mensagem)
    db.session.add(novo_dado)
    db.session.commit()
    flash('Sua mensagem foi enviada com sucesso!', 'success')
    return redirect(url_for('main.contato'))

    @main.route("/mostrar_produtos", methods=["GET"])
    def mostrar_produtos():
    produtos = Produto.query.all()
    return jsonify([produto.to_json() for produto in produtos])

    @main.route("/produto/<int:id>", methods=["GET"])
    def mostrar_produto(id):
    produto = Produto.query.get(id)
    if produto is None:
    abort(404)
    return jsonify(produto.to_json())

    # --- Functions ---
    def allowed_file(filename): # Removed app_config parameter
    return '.' in filename and \
    filename.rsplit('.', 1)[1].lower() in current_app.config['ALLOWED_EXTENSIONS']

    def save_picture(form_picture): # Removed app_instance parameter
    random_hex = os.urandom(8).hex()
    _, f_ext = os.path.splitext(form_picture.filename)
    picture_fn = random_hex + f_ext
    picture_path = os.path.join(current_app.root_path, current_app.config['UPLOAD_FOLDER'], picture_fn)

    output_size = (125, 125)
    i = Image.open(form_picture)
    i.thumbnail(output_size)
    i.save(picture_path)

    return picture_fn

    # --- Product Routes ---
    @main.route('/product/new', methods=['GET', 'POST'])
    @login_required
    def add_product():
    form = ProductForm()
    if form.validate_on_submit():
    picture_file = 'default.jpg'
    if form.image.data:
    picture_file = save_picture(form.image.data) # No need to pass current_app

    product = Produto(name=form.name.data, price=form.price.data,
    description=form.description.data, image_file=picture_file)
    db.session.add(product)
    db.session.commit()
    flash('Produto adicionado com sucesso!', 'success')
    return redirect(url_for('main.index'))
    return render_template('add_product.html', title='Adicionar Produto', form=form)

    @main.route('/product/<int:product_id>')
    def product(product_id):
    product = Produto.query.get_or_404(product_id)
    return render_template('product.html', title=product.name, product=product)

    @login_required
    @main.route('/product/<int:product_id>/edit', methods=['GET', 'POST'])
    def edit_product(product_id):
    product = Produto.query.get_or_404(product_id)
    form = ProductForm()
    if form.validate_on_submit():
    if form.image.data:
    if product.image_file != 'default.jpg':
    old_image_path = os.path.join(current_app.root_path, current_app.config['UPLOAD_FOLDER'], product.image_file)
    if os.path.exists(old_image_path):
    os.remove(old_image_path)
    picture_file = save_picture(form.image.data)
    product.image_file = picture_file
    product.name = form.name.data
    product.price = form.price.data
    product.description = form.description.data
    db.session.commit()
    flash('Produto atualizado com sucesso!', 'success')
    return redirect(url_for('main.product', product_id=product.id))
    elif request.method == 'GET':
    form.name.data = product.name
    form.price.data = product.price
    form.description.data = product.description
    return render_template('edit_product.html', title='Editar Produto', form=form, product=product)

    @login_required
    @main.route('/product/<int:product_id>/delete', methods=['POST'])
    def delete_product(product_id):
    product = db.session.get(Produto, product_id)
    if product is None:
    abort(404)

    if product.image_file != 'default.jpg':
    image_path = os.path.join(current_app.root_path, current_app.config['UPLOAD_FOLDER'], product.image_file)
    if os.path.exists(image_path):
    os.remove(image_path)

    db.session.delete(product)
    db.session.commit()
    flash('Produto excluído com sucesso!', 'success')
    return redirect(url_for('main.index'))

    # --- Application Factory ---
    def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)

    # Initialize extensions with the app
    db.init_app(app)


    # Register Blueprints
    app.register_blueprint(main)

    return app

    if __name__ == '__main__':
    app = create_app()
    with app.app_context():
    db.create_all()
    app.run(debug=True)
    `````
    here is the models.py:
    ````
    # models.py
    from datetime import datetime
    from .extensions import db
    from flask_login import UserMixin # Keep UserMixin import



    class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), unique=True, nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)
    password = db.Column(db.String(200), nullable=False)

    def __repr__(self):
    return f"User('{self.name}', '{self.email}')"



    class Produto(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    price = db.Column(db.Float, nullable=False)
    description = db.Column(db.Text, nullable=False)
    image_file = db.Column(db.String(20), nullable=False, default='default.jpg')

    def to_json(self):
    return {
    'id': self.id,
    'name': self.name,
    'price': self.price,
    'description': self.description,
    'image_file': self.image_file
    }

    class DadosFormulario(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    nome = db.Column(db.String(100), nullable=False)
    email = db.Column(db.String(100), nullable=False)
    estado = db.Column(db.String(100), nullable=True)
    cidade = db.Column(db.String(100), nullable=True)
    mensagem = db.Column(db.Text, nullable=False)
    data_envio = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    ````
    and extensions.py:
    ````
    from flask_sqlalchemy import SQLAlchemy
    from flask_login import LoginManager
    login_manager = LoginManager() # Initialize LoginManager here as well
    db = SQLAlchemy()
    `````

    Continue reading...

Compartilhe esta Página