Как использовать Neo4j-внедренный для Python (потоки) в микросхеме Flask?
Я следую Flask Tutorial (Flaskr), чтобы поэкспериментировать с использованием Neo4j-внедренного для Python. Это в virtualenv. Вот мой «основной» код приложения:
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-внедренными. Первоначально JVM завершится сбоем, и приложение завершит работу, когда я запросю index (). Я просмотрел сеть, чтобы узнать, что мне нужно добавить строку «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.
Поиск в Google по всей последней строке никуда не делся. Просто поиск "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 работали с многопоточным запросом, а не только с «основным» приложением?
Примечание: я знаю о решениях RESTful Web Service с py2neo или Rexster / Bulbs, но пока хочу этого избежать.
РЕДАКТИРОВАТЬ: Использование JPype-0.5.4.2, Neo4j-embedded-1.5.b2, Java-6-openjdk