2016-05-23 6 views
0

Я только что начал играть с новым драйвером neo4j для python и полностью застрял в транзакциях. Как проверить успешную транзакцию? Насколько я могу сказать, функция commit не вызывает автоматически ошибки, т. Е. Если, например, я предоставляю ей неверный запрос Cypher, я не получаю никакой информации об этом.драйвер Neo4j - подтверждение транзакции

Я попытался чтением last_result аргумента от Session объекта и придумал STH как:

import neo4j.v1 as neo 

def db_confirm_transaction_success(session): 
    try: 
     w = list(session.last_result) 
     return True 
    except neo.CypherError as e: 
     session.last_result._consumed = True 
     return False 
    except neo.ResultError as e: 
     session.last_result._consumed = True 
     return False 

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

Заранее спасибо за помощь.

Редактировать: Только, чтобы уточнить, атрибут Transaction.success указывает, должна ли транзакция быть совершена или откат. Однако, например, Ошибки Cypher можно идентифицировать как опоздание времени выполнения запросов.

ответ

1

Я стучал головой о том же, пока не дал сообщение developer manual.

До сих пор я не мог понять, почему запуск нескольких неудачных утверждений с session.run(statement) не вызвал бы исключение, а скорее session.close().

Тогда я попытался использовать что-то вроде:

with session.begin_transaction() as tx: 
    tx.run(statement) 
    tx.success = True 

Если вы не хотите, чтобы менеджер контекста, вы можете использовать:

tx = session.begin_transaction() 
tx.run(statement) 
tx.commit() 

Если вы читаете python docs вы можете заметить tx.commit() является такой же предмет как бег tx.success=True и tx.close().

Проблема с этим заключается в том, что вызов commit() только добавляет сообщение cypher COMMIT в поток соединения. Насколько мне известно, он не проверяет успех транзакции.


После прочтения раздела 18 в руководстве, я обнаружил, что, потому что я был явно не потребляя результатов, не было гарантирует, что это заявление было обработано, так как библиотека с помощью отложенной загрузки (-поисковых результатов только по требованию) , См записки с 18,1 ниже:.

«Результат запись загружается лениво, как курсор перемещается через поток Это означает, что курсор должен быть перемещен в первый результат до этого результата можно потребляется Это также средство. что весь поток должен быть явно потреблен до . Доступна сводная информация и метаданные. Как правило, наилучшая практика заключается в том, что явно потребляет результаты и закрывает сеансы, в частности, при выполнении обновлений . Это относится даже к тому, что сводная информация не требуется. В противном случае результат может привести к непредсказуемому поведению, так как не будет никакой гарантии , что сервер видел и обрабатывал Cypher s tatement.. "


Таким образом, по существу, вы должны явно потреблять ваши результаты после запуска Cypher заявление Это можно сделать так:

res = session.run(statement) # or the equivalent iusing transaction style 
res.consume() 

Я заметил, что функция .consume() вызывает list(self) перебрать все результаты (класс StatementResult определяет метод __iter__) .Так что, хотя я его не тестировал, может случиться так, что для простого перебора результатов используется для вас потребление:

res = session.run(statement) 
for r in res: 
    continue 

Надеюсь, это поможет!

Смежные вопросы