Как использовать Neo4j-внедренный для Python (потоки) в микросхеме Flask? - PullRequest
4 голосов
/ 03 ноября 2011

Я следую инструкциям 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 и jpype работали с многопоточным запросом, а не только с «основным» приложением?

Примечание.решения RESTful Web Service с py2neo или Rexster / Bulbs, но сейчас я хочу этого избежать.

РЕДАКТИРОВАТЬ: Использование JPype-0.5.4.2, Neo4j-embedded-1.5.b2, Java-6-openjdk

Ответы [ 2 ]

6 голосов
/ 04 ноября 2011

Одна из проблем, связанных с этим шаблоном, заключается в том, что вы рискуете запустить несколько баз данных, указанных в одном месте, что приведет к проблемам.То, что вы хотели бы, это один экземпляр базы данных, который следует за полным жизненным циклом вашего приложения.

Почему не удается найти поставщика lucene, это более сложный вопрос. Поставщик индекса загружается с помощью загрузчика службы java, которыйозначает, что JPype не должен влиять на это.Пока JVM запускается нормально, а jar реализации lucene-index находится на пути к классам, он должен работать.

Это может быть как-то связано с многопоточностью, в настоящее время я пишу исправление для автоматической обработки "attachThreadToJVM () "вызывает.Я добавлю тестовый пример, чтобы убедиться, что чтение индексов из отдельного потока также работает должным образом.

Работа с потоками в настоящее время обновляется в этой теме списка рассылки:

http://neo4j -community-discussions.438527.n3.nabble.com / Neo4j-Python-встраивание-проблемы-с-выключение-и-нити-td3476163.html

3 голосов
/ 04 ноября 2011

Попытался воспроизвести ошибку, используя чистую установку neo4j, flask и jpipe, используя стандартный путь Java по умолчанию.Не удалось создать этот журнал.Но я получил ошибку

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "teststack.py", line 27, in initDB
    userIndex = db.node.indexes.create('users')
 File "/usr/local/lib/python2.7/dist-packages/neo4j/index.py", line 32, in create
   return self._index.forNodes(name, to_java(config))
 jpype._jexception.RuntimeExceptionPyRaisable: java.lang.IllegalArgumentException:      Supplied index configuration:
{}
doesn't match stored config in a valid way:
{provider=lucene, type=exact}
for 'users'

при использовании initDB

, исправленную с

userIndex = db.node.indexes.create(users)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...