Reputation: 3736
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
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
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