Skip to content

Instantly share code, notes, and snippets.

@aanastasiou
Last active October 25, 2023 13:21
Show Gist options
  • Save aanastasiou/8e2ffdf9a5dd87954e013ff99ef92f91 to your computer and use it in GitHub Desktop.
Save aanastasiou/8e2ffdf9a5dd87954e013ff99ef92f91 to your computer and use it in GitHub Desktop.
Using neomodel with Flask
import neomodel
class Item(neomodel.StructuredNode):
__primarykey__ = "name"
name = neomodel.StringProperty(unique_index=True)
"""
A simple example showing how using neomodel with Flask in a naive way
can lead to exceptions.
This example is based on code found in this stack-overflow post:
https://stackoverflow.com/questions/52877575/flask-and-neomodel-modeldefinitionmismatch
!!! WARNING !!!
* Prior to running this example, please make sure that the NEO4J_BOLT_URL environment
variable, points to a working and properly setup instance of a neo4j dbms.
///FOLLOW THE CODE LINE-TO-LINE TO GET A COHERENT NARRATIVE FROM THE INLINE COMMENTS///
"""
import os
import json
import flask
import neomodel
class Item(neomodel.StructuredNode):
__primarykey__ = 'name'
name = neomodel.StringProperty(unique_index=True)
def create_an_item():
neomodel.db.set_connection(os.environ['NEO4J_BOLT_URL'])
Item(name='Something Something Dark Side').save()
def create_app():
"""
This is the original way presented to create a class. Please note
the inline comments throughout
"""
# In this example a Flask application is created explicity.
app = flask.Flask(__name__)
neomodel.config.DATABASE_URL = os.environ['NEO4J_BOLT_URL']
# At this point, the neomodel.db object has been initialised as expected
@app.route('/', methods=['GET'])
def get_all_items():
# At the time this function gets to be called, it operates in a different
# process and therefore the neomodel.db that is used implicitly in retrieving
# the Item from the database is completely different than the neomodel.db that
# that was initialised in the process of execution that created the app object.
# Anything running within the request serving functions is entirely independent stand-alone code.
return flask.jsonify({'items': [item.name for item in Item.nodes]})
return app
if __name__ == '__main__':
# !!!PRIOR TO RUNNING THE APP, CREATE AT LEAST ONE Item IN THE DATABASE!!!
create_an_item()
# Comment the above line and uncomment the following two to launch the app
# flask_app = create_app()
# At this point, the neomodel.db object used in this process is configured and valid
# flask_app.run()
# At this point, the neomodel.db object stays configured and valid
# IN THIS THREAD OF EXECUTION
#
# For every subsequent request, a completely new process
# is created. The neomodel.db object within THAT thread of execution
# would not have undergone the kind of preparation it has for this
# process. Consequently, its _NODE_CLASS_REGISTRY would be empty
# and any attempt to instantiate objects from the app's model would
# fail.
"""
Continuing from the above example, here is the _naive_ way of fixing the problem.
What is different in this script is the way that the neomodel.db object is being managed.
!!! WARNING !!!
* Prior to running this example, please make sure that the NEO4J_BOLT_URL environment
variable, points to a working and properly setup instance of a neo4j dbms.
///FOLLOW THE CODE LINE-TO-LINE TO GET A COHERENT NARRATIVE FROM THE INLINE COMMENTS///
"""
import os
import json
import flask
import neomodel
# !!! NOTICE REMOVAL OF THIS INSTANTIATION STEP !!!
# import appmodels
def create_an_item():
neomodel.db.set_connection(os.environ['NEO4J_BOLT_URL'])
appmodels.Item(name='Something Something Dark Side').save()
def create_app():
"""
This is the original way presented to create a class. Please note
the inline comments throughout
"""
# In this example a Flask application is created explicity.
app = flask.Flask(__name__)
neomodel.config.DATABASE_URL = os.environ['NEO4J_BOLT_URL']
# At this point, the neomodel.db object has been initialised as expected
@app.route('/', methods=['GET'])
def get_all_items():
# !!! NOTICE ADDITION OF THIS INITIALISATION STEP !!!
import appmodels
return flask.jsonify({'items': [item.name for item in appmodels.Item.nodes]})
return app
if __name__ == "__main__":
# !!!PRIOR TO RUNNING THE APP, CREATE AT LEAST ONE Item IN THE DATABASE!!!
create_an_item()
# Comment the above line and uncomment the following two to launch the app
# flask_app = create_app()
# At this point, the neomodel.db object is configured and valid
# flask_app.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment