Flask-SQLAlchemy db.create_all() raises RuntimeError working outside of application context

Question:

I recently updated Flask-SQLAlchemy, and now db.create_all is raising RuntimeError: working outside of application context. How do I call create_all?

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///project.db'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)

db.create_all()

This raises the following error:

Traceback (most recent call last):
  File "/home/david/Projects/flask-sqlalchemy/example.py", line 11, in <module>
    db.create_all()
  File "/home/david/Projects/flask-sqlalchemy/src/flask_sqlalchemy/extension.py", line 751, in create_all
    self._call_for_binds(bind_key, "create_all")
  File "/home/david/Projects/flask-sqlalchemy/src/flask_sqlalchemy/extension.py", line 722, in _call_for_binds
    engine = self.engines[key]
  File "/home/david/Projects/flask-sqlalchemy/src/flask_sqlalchemy/extension.py", line 583, in engines
    app = current_app._get_current_object()  # type: ignore[attr-defined]
  File "/home/david/Projects/flask-sqlalchemy/.venv/lib/python3.10/site-packages/werkzeug/local.py", line 513, in _get_current_object
    raise RuntimeError(unbound_message) from None
RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that needed
the current application. To solve this, set up an application context
with app.app_context(). See the documentation for more information.
Asked By: Huzairi Haril

||

Answers:

As of Flask-SQLAlchemy 3.0, all access to db.engine (and db.session) requires an active Flask application context. db.create_all uses db.engine, so it requires an app context.

with app.app_context():
    db.create_all()

When Flask handles requests or runs CLI commands, a context is automatically pushed. You only need to push one manually outside of those situations, such as while setting up the app.


Instead of calling create_all in your code, you can also call it manually in the shell. Use flask shell to start a Python shell that already has an app context and the db object imported.

$ flask shell
>>> db.create_all()

Or push a context manually if using a plain python shell.

$ python
>>> from project import app, db
>>> app.app_context().push()
>>> db.create_all()
Answered By: davidism

If you’re using a python shell instead of flask shell, you can push a context manually. flask shell will handle that for you.

>>> from project import app, db
>>> app.app_context().push()
>>> db.create_all()

Learn more about the application context in the Flask docs or this video.

Answered By: Yusharth Singh

Here’s an example.py that configures a SQLite database, a model, then creates the database. The with app.app_context() line around db.create_all() is what’s needed to avoid the context error.

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db"
db = SQLAlchemy()

class Article(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String)
    body = db.Column(db.String)

with app.app_context():
    db.create_all()

Run the development server with this command, and the database will be created if it doesn’t exist.

$ flask -A example.py --debug run
Answered By: Ajiroghene
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.