我刚刚开始使用新的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错误可以在查询后期识别出来。执行时间。
答案 0 :(得分:2)
我正在敲打同一件事,直到我给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()
只会在连接的流中添加COMMIT
个cypher消息。据我所知,它不能验证交易是否成功。
在阅读手册中的第18节之后,我发现由于我没有明确地使用结果,因此没有保证语句被处理,因为库使用延迟加载(仅根据需要撤回结果)。见下面18.1的说明:
“当光标在流中移动时,结果记录会被懒惰地加载 表示必须在此结果之前将光标移动到第一个结果 消耗。这也意味着必须在之前明确地使用整个流 提供摘要信息和元数据。通常最好的做法是 显式使用结果和关闭会话,特别是在运行更新时 声明。即使不需要摘要信息,这也适用。没有 消费结果可能导致不可预测的行为,因为无法保证 服务器已经看到并处理了Cypher声明。“
因此,基本上,您需要在运行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
希望这有帮助!