mortymacs
mortymacs

Reputation: 3736

Access to Flask Global Variables in Blueprint Apps

my source code has this structure:

main.py:

from flask import Flask, g
app = Flask(__name__)
with app.app_context():
    g.my_db = PostgreSQL()
    app.register_blueprint(my_app, url_prefix="/my_app")

my_app.py:

from flask import Blueprint, g
my_app = Blueprint("my_app", __name__)
@my_app.route("/")
def index():
    return g.my_db.fetch_all()   <<< ERROR

but it shows this error:

AttributeError: '_AppCtxGlobals' object has no attribute 'my_db'

Even when I try to use g outside of app context, it shows this error:

RuntimeError: Working outside of application context.

So how to set and access to global variables in Flask?

Upvotes: 8

Views: 7661

Answers (2)

Ali Yılmaz
Ali Yılmaz

Reputation: 1695

g isn't persistent in the way you're trying to use it. Write a function to create a connection each time you need it. Preferably use a database extension like Flask-SQLAlchemy to manage connections for you.

db.py:

import <postgresql dependencies>

def get_db():
   db = PostgreSQL()
   # config here
   return db

main.py:

from flask import Flask

app = Flask(__name__)
app.register_blueprint(my_app, url_prefix="/my_app")

my_app.py:

from flask import Blueprint, g
from db import get_db

my_app = Blueprint("my_app", __name__)

@my_app.route("/")
def index():
    db = get_db()
    data = db.fetch_all()
    db.close()
    return data

Upvotes: 2

PRMoureu
PRMoureu

Reputation: 13317

This happens because the data are lost when the context (with app.app_context()) ends (doc).

Inside the context, everything is ok :

from flask import Flask, g
app = Flask(__name__)
with app.app_context():
    g.my_db = 'database ok'
    print(g.my_db)

# >>> this prints 'database ok'

But outside, you cannot access the attribute :

from flask import Flask, g
app = Flask(__name__)
with app.app_context():
    g.my_db = 'database ok'

print(g.my_db)

# >>> this throws RuntimeError: Working outside of application context

even if you create a new context:

from flask import Flask, g
app = Flask(__name__)
with app.app_context():
    g.my_db = 'database ok'

with app.app_context():
    print(g.my_db)

>>> this throws AttributeError: '_AppCtxGlobals' object has no attribute 'my_db'

Your best call should be to declare the database object before the context, and then import it. Or maybe you can create it directly inside my_app.py where you need it ?

Upvotes: 4

Related Questions