Search code examples
flaskflask-sqlalchemy

Why is my "g" object from Flask not providing information?


I just started learning Flask today. And I am trying to follow best practices. So I added my user data to the "g" object from Flask. And in the beginning it worked fine.

@some_blueprint.before_request
    def handleAuthentication():
        # Do some auth logic
        # Add user data to Flask "g" object
        g.user = {userId: 'somevalue'}
        print(g.get('user')) # PRINTS OUT USER DATA

And it also worked inside of the route handler

@some_blueprint.route("/some-route", methods=['GET'])
def handleController():
    print(g.get('user')) # PRINTS OUT USER DATA
    return controller()

But for some reason it is not working inside of the controller that is invoked inside of the route handler.

def controller():
    print(g.get('user')) # DOES NOT PRINT OUT USER DATA
    # Some Logic

How can I get the controller to have access to the same data that the "authentication" and "handleController" method have?

Also I did encounter an issue earlier where when I used the db.sesssion.add and db.session.commit methods they gave me an error talking about "The current Flask app is not registered with this 'SQLAlchemy' instance. Did you forget to call 'init_app', or did you create multiple 'SQLAlchemy' instances. I fixed it by wrapping my controllers with this code

with app.app_context():
    # NOW DB.SESSION.ADD AND DB.SESSION.COMMIT WORKS

So although it works now I don't really understand why? My guess is that when you modularize your Python code (break it up into pieces to make it easier to navigate), SQLAlchemy is unable to identify the information regarding your database. Because if you use this in the "app.py" file you have no problem doing this. Its only when you modularize. Correct me if I'm wrong. I'm just guessing based on my experiences.


Solution

  • I fixed it by taking the data from the "handleController" function and passing it into the "controller" function.

    And for some cases where you wan't to wrap your function with another function just use a lambda. This way your not invoking it right away.