user7225011
user7225011

Reputation:

Keeping py2neo connection in Flask's application context

I'm using py2neo without a flask extension (since it behaves quite strangely) in my flask project.
What I'm trying to do, is to preserve my database connection in the application context (since it is preserved during the entire request handling, right?).

Based on flask's documentation, I have the following code:

def get_neo4j():
    with app.app_context():
        neo4j = getattr(g, '_neo4j', None)
        if neo4j is None:
            connection_string = http blah blah blah
            neo4j = g._neo4j = Graph(connection_string)
        return neo4j  

Is this correct? How can I edit the above code to benefit from werkzeug's local proxy?

Upvotes: 2

Views: 419

Answers (1)

user7225011
user7225011

Reputation:

Ok, After reading Flask's documentation on extensions, it was simple to develop my own class to keep the connection alive:

from py2neo import Graph
from flask import current_app

try:
    from flask import _app_ctx_stack as stack
except ImportError:
    from flask import _request_ctx_stack as stack


class Neo4jConnection(object):

    def __init__(self, app=None):
        self.app = app
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        if hasattr(app, 'teardown_appcontext'):
            app.teardown_appcontext(self.teardown)
        else:
            app.teardown_request(self.teardown)

    def connect(self):
        # Read configuations from app config
        return Graph(bolt=True,
                     host=current_app.config['NEO4J_SERVER_ADDRESS'],
                     bolt_port=current_app.config['NEO4J_PORT'],
                     user=current_app.config['NEO4J_USER'],
                     password=current_app.config['NEO4J_PASSWORD'],)

    def teardown(self, exception):
        ctx = stack.top
        if hasattr(ctx, 'neo4j_db'):
            ctx.neo4j_db = None

    @property
    def connection(self):
        ctx = stack.top
        if ctx is not None:
            if not hasattr(ctx, 'neo4j_db'):
                ctx.neo4j_db = self.connect()
            return ctx.neo4j_db

Now use the factory pattern to get it working:

Initialization:

neo4j = Neo4jConnection()
neo4j.init_app(app)

Usage:

myneo = Neo4jConnection().connection
myneo.push(.....)

I have tested it. Hope it's correct.

Upvotes: 1

Related Questions