Maksim Levchenko
Maksim Levchenko

Reputation: 87

How to fix "RuntimeError: Working outside of application context." when creating blueprints with Flask?

I'm trying to create a Blueprint and ran into this problem:

Traceback (most recent call last):
  File "C:\Users\Max\PycharmProjects\python1\flask_first\__init__.py", line 3, in <module>
    from models import db
  File "C:\Users\Max\PycharmProjects\python1\flask_first\models.py", line 5, in <module>
    current_app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.sqlite3.html'  # access to the SQL
  File "C:\python3.9\lib\site-packages\werkzeug\local.py", line 347, in __getattr__
    return getattr(self._get_current_object(), name)
  File "C:\python3.9\lib\site-packages\werkzeug\local.py", line 306, in _get_current_object
    return self.__local()
  File "C:\python3.9\lib\site-packages\flask\globals.py", line 52, in _find_app
    raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context().  See the
documentation for more information.

I've already done a lot of research and nothing works for me (or I'm just not looking properly enough).

This is the models.py code:

from flask_sqlalchemy import SQLAlchemy
from flask import current_app


current_app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.sqlite3.html'  # access to the SQL
current_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(current_app)

class users(db.Model):
    __tablename__ = 'users'
    _id = db.Column('id', db.Integer, primary_key=True)
    name = db.Column(db.String(80))
    email = db.Column(db.String(120))
    password = db.Column(db.Integer)

    def __init__(self, name, email, password):
        self.name = name
        self.email = email
        self.password = password

And this is the __init__.py:

from datetime import timedelta
from flask import Flask
from models import db
from flask_first.admin.second import second

def create_app():
    app = Flask(__name__)
    with app.app_context():

        db.init_app(app)
    return app

create_app.secret_key = 'hello world'
create_app.permanent_session_lifetime = timedelta(minutes=5)  # setting the time for long-lasting session

if __name__ == '__main__':
    db.create_all()
    create_app.run(debug=True)

Here is a screenshot of my structure:
file/folder structure

Upvotes: 1

Views: 20348

Answers (2)

MD Kawsar
MD Kawsar

Reputation: 437

For me I just add app.app_context().push() and it works for me!

see the whole code below:

Filename is basic.py

import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

basedir = os.path.abspath(os.path.dirname(__file__))

app = Flask(__name__)

app.app_context().push()

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join('data.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

class Person(db.Model):

    # Manual Table Name Choice
    __tablename__ = 'puppies'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Text)
    age = db.Column(db.Integer)

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        return f"Person {self.name} is {self.age} Yea/s Old"

The running file name is as: setupdatabase.py

from basic import db, Person

db.create_all()

demo1 = Puppy('Eva', 30)
demo2 = Puppy('kawsar', 40)

db.session.add_all([demo1, demo2])
db.session.commit()

Upvotes: -1

Gino Mempin
Gino Mempin

Reputation: 29608

Here I'll expand on my comment into an answer.

Python executes your code line-by-line, and that includes import statements. As the error indicates, when it entered __init__.py and got to the from models import db line, it immediately jumped to models.py, and started executing your lines there.

Traceback (most recent call last):
  File "...\__init__.py", line 3, in <module>
    from models import db
  File "...\models.py", line 5, in <module>
    current_app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.sqlite3.html'

At this point, the imported current_app does not exist yet, because the create_app from __init__.py seems to have not been called yet. This is where you'll get the common Flask error of "working outside of application context:

RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context().  See the
documentation for more information.

Most of the time you get this type of error, the solution is to reorder your initialization codes. Make sure that the Flask app instance is already created before you do anything else. It should usually be the first thing your code does.

Following the Quickstart tutorial from flask-sqlalchemy, you can put the db object initialization near the app initialization.

# Create app object
app = Flask(__name__)

# Set configs
app.config['...'] = ...

# Create db object
db = SQLAlchemy(app)

The app and db objects typically reside together in some top-level main module. Then, in your other sub-modules (controllers, models, etc.) where you need to setup each component separately, import the app and/or db from the main module:

from some_main_module import app, db

# Do stuff with app and db

Upvotes: 5

Related Questions