Драйвер Neo4j - подтвердить успешность транзакции

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

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

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 могут быть идентифицированы уже во время выполнения запросов.

2 ответа

Я бился головой об одном и том же, пока не прочитал руководство для разработчика.

До этого я не мог понять, почему несколько плохих утверждений с 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, вы можете заметить, tx.commit() это то же самое, что бег tx.success=True а также tx.close(),

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


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

"Записи результатов загружаются лениво, когда курсор перемещается по потоку. Это означает, что курсор должен быть перемещен к первому результату, прежде чем этот результат может быть использован. Это также означает, что весь поток должен быть явно использован перед сводной информацией и метаданными обычно рекомендуется явным образом использовать результаты и закрывать сеансы, в частности, при выполнении операторов обновления. Это применимо, даже если сводная информация не требуется. Отказ от использования результата может привести к непредсказуемому поведению, поскольку не будет никакой гарантии что сервер видел и обработал оператор 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

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

Просто хотел опубликовать обновленный ответ для Neo4j 4.x.

      def commit_data(query):
    with driver.session(database="neo4j") as session:
        tx = session.begin_transaction()
        result = tx.run(query)
        result = [dict(i) for i in result]
        
       # uncomment below line to see the complete txn summary.
        # print(result) 

        if result[0]['failedOperations']>0:
            print(query)
            print(result)
            raise 'Error! Please recheck your query.'
        
        tx.commit()

Надеюсь, это поможет другим.

Другие вопросы по тегам