我正在关注Flask教程(Flaskr),以便尝试使用Neo4j-embedded for Python.这是一个虚拟的.这是我的"主要"应用代码:
import os import jpype from neo4j import GraphDatabase from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash app = Flask(__name__) app.config.from_pyfile(os.environ['APP_SETTINGS']) def connectDB(): return GraphDatabase(app.config['DATABASE']) def initDB(): db = connectDB() with db.transaction: users = db.node() roles = db.node() db.reference_node.USERS(users) db.reference_node.ROLES(roles) userIndex = db.node.indexes.create('users') user = db.node(name=app.config['ADMIN']) user.INSTANCE_OF(users) userIndex['name'][app.config['ADMIN']] = user role = db.node(type='superadmin') role.INSTANCE_OF(roles) role.ASSIGN_TO(user) db.shutdown() print "Database initialized." def testDB(): db = connectDB() with db.transaction: userIndex = db.node.indexes.get('users') user = userIndex['name'][app.config['ADMIN']].single username = user['name'] db.shutdown() print "Admin username is '%s'. Database exists." % username @app.before_request def before_request(): jpype.attachThreadToJVM() g.db = connectDB() @app.teardown_request def teardown_request(exception): g.db.shutdown() @app.route('/') def index(): with g.db.transaction: userIndex = g.db.node.indexes.get('users') user = userIndex['name'][app.config['ADMIN']].single username = user['name'] fields = dict(username=username) return render_template('index.html', fields=fields) if os.path.exists(app.config['DATABASE']) == False: initDB() else: testDB()
initDB()和testDB()工作得很好 - 没有Gremlin,PyLucene等 - 只是jpype和neo4j-embedded.最初,当我请求index()时,JVM将失败并且应用程序将终止.我在网上搜索了解我需要将"jpype.attachThreadToJVM()"行添加到before_request()中以解决python线程化JVM并且应用程序未终止的问题.但是,这会立即导致另一个问题:
Traceback (most recent call last): File "/ht/dev/envFlask/lib/python2.7/site-packages/flask/app.py", line 1518, in __call__ return self.wsgi_app(environ, start_response) File "/ht/dev/envFlask/lib/python2.7/site-packages/flask/app.py", line 1506, in wsgi_app response = self.make_response(self.handle_exception(e)) File "/ht/dev/envFlask/lib/python2.7/site-packages/flask/app.py", line 1504, in wsgi_app response = self.full_dispatch_request() File "/ht/dev/envFlask/lib/python2.7/site-packages/flask/app.py", line 1264, in full_dispatch_request rv = self.handle_user_exception(e) File "/ht/dev/envFlask/lib/python2.7/site-packages/flask/app.py", line 1262, in full_dispatch_request rv = self.dispatch_request() File "/ht/dev/envFlask/lib/python2.7/site-packages/flask/app.py", line 1248, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "/ht/dev/apps/evobox/evobox/__init__.py", line 68, in index userIndex = g.db.node.indexes.get('users') File "/ht/dev/envFlask/lib/python2.7/site-packages/neo4j/index.py", line 36, in get return self._index.forNodes(name) java.lang.RuntimeExceptionPyRaisable: java.lang.IllegalArgumentException: No index provider 'lucene' found. Maybe the intended provider (or one more of its dependencies) aren't on the classpath or it failed to load.
谷歌搜索整个最后一行并没有去任何地方.只是搜索"java.lang.IllegalArgumentException:找不到索引提供者'lucene'." 在python的上下文中没有任何结果.
neo4j messages.log似乎显示数据库已打开3次(initDB(),testDB()和index()).每个实例的类路径相同:
Class Path: /ht/dev/envFlask/local/lib/python2.7/site-packages/neo4j/javalib/neo4j-jmx-1.5.M02.jar:/ht/dev/envFlask/local/lib/python2.7/site-packages/neo4j/javalib/neo4j-lucene-index-1.5.M02.jar:/ht/dev/envFlask/local/lib/python2.7/site-packages/neo4j/javalib/neo4j-graph-matching-1.5.M02.jar:/ht/dev/envFlask/local/lib/python2.7/site-packages/neo4j/javalib/neo4j-1.5.M02.jar:/ht/dev/envFlask/local/lib/python2.7/site-packages/neo4j/javalib/neo4j-kernel-1.5.M02.jar:/ht/dev/envFlask/local/lib/python2.7/site-packages/neo4j/javalib/geronimo-jta_1.1_spec-1.1.1.jar:/ht/dev/envFlask/local/lib/python2.7/site-packages/neo4j/javalib/lucene-core-3.1.0.jar:/ht/dev/envFlask/local/lib/python2.7/site-packages/neo4j/javalib/neo4j-graph-algo-1.5.M02.jar:/ht/dev/envFlask/local/lib/python2.7/site-packages/neo4j/javalib/neo4j-udc-1.5.M02.jar:/ht/dev/envFlask/local/lib/python2.7/site-packages/neo4j/javalib/neo4j-cypher-1.5.M02.jar:/ht/dev/envFlask/local/lib/python2.7/site-packages/neo4j/javalib/scala-library-2.9.0-1.jar
我还直接将index()修改为connectDB和attachThreadToJVM,如initDB()和testDB(),而不使用'g'全局 - 这导致完全相同的错误.
我可能缺少什么/忽略让neo4j-embedded和jpype处理线程请求而不只是在'main'应用程序中?
注意:我知道使用py2neo或Rexster/Bulbs的RESTful Web服务解决方案,但我现在想要避免这种情况.
编辑:使用JPype-0.5.4.2,Neo4j-embedded-1.5.b2,Java-6-openjdk
此模式的一个问题是您冒着启动指向同一位置的多个数据库的风险,这将导致问题.您需要的是在应用程序的整个生命周期之后的数据库的单个实例.
为什么它没有找到lucene提供者是一个更难的问题..索引提供程序是使用java服务加载器加载的,这意味着JPype不应该影响它.只要JVM启动正常,并且lucene-index实现jar在类路径上,它应该可以工作.
它可能与某种程度上的线程有关,我正在编写一个修复程序来自动处理"attachThreadToJVM()"调用.我将添加一个测试用例,以确保从单独的线程读取索引也能按预期工作.
线程工作目前在此邮件列表线程中保持更新:
http://neo4j-community-discussions.438527.n3.nabble.com/Neo4j-Python-embedding-problems-with-shutdown-and-threads-td3476163.html