为什么ArangoDB(使用Python-Arango)返回ERR 1600 ERROR_CURSOR_NOT_FOUND?

时间:2018-07-31 12:49:11

标签: python arangodb

问题

我遍历整个顶点集合,例如journals,并用它来创建从author到给定person的边journal

我使用python-arango,代码类似于:

for journal in journals.all():
    create_author_edge(journal)

我有一个相对较小的数据集,而journals集合只有大约ca。 1300个文档。但是:大于1000 ,这是Web界面中的批处理大小-但我不知道这是否有意义。

问题在于它引发一个CursorNextError,并从数据库ERROR_CURSOR_NOT_FOUND error返回HTTP 404ERR 1600

  

当通过其ID请求一个游标但找不到具有该ID的游标时,将引发该事件。

对原因的洞察力

ArangoDB Cursor Timeoutthis issue开始,我怀疑这是因为游标的TTL在数据库中已到期,并且在python stacktrace中看到了这样的内容:

# Part of the stacktrace in the error:
(...)
if not cursor.has_more():
    raise StopIteration
cursor.fetch()  <---- error raised here
(...)

如果我快速遍历整个集合,即如果我进行print(len(journals.all()),它将输出“ 1361”而没有错误。

当我用AQL替换journals.all()并增加TTL参数时,它可以正常工作:

for journal in db.aql.execute("FOR j IN journals RETURN j", ttl=3600):
    create_author_edge(journal)

但是,在没有ttl参数的情况下,AQL方法产生的错误与使用journals.all()的错误相同。

更多信息

最后一条信息是出现错误时,我正在个人笔记本电脑上运行此信息。在我的工作计算机上,使用相同的代码创建图形并使用相同的数据填充图形,但未引发任何错误。因为我正在休假,所以我无法使用工作计算机来比较版本,但是两个系统都是在夏季安装的,因此版本相同的可能性很大。

问题

我不知道这是python-arango还是ArangoDB的问题。我相信,因为增加TTL没问题,这可能表明ArangodDB而不是Python驱动程序有问题,但我不知道。

(我添加了一个功能请求,即将ttl-param添加到.all()方法here。)

对为什么发生这种情况有任何见解吗?


我没有代表来创建标签“ python-arango”,所以如果有人创建它并为我的问题添加标签,那就太好了。

2 个答案:

答案 0 :(得分:1)

在服务器内部,简单查询将转换为all()。 正如所引用的github问题所讨论的那样,简单查询不支持TTL参数,也不会得到它们。

这里的首选解决方案是在客户端上使用AQL查询,以便您可以指定TTL参数。

通常,应避免立即从数据库中提取所有文档,因为这可能会带来其他扩展问题。您应该对带有索引支持的FILTER语句使用正确的AQL(使用explain()进行验证)来获取所需的文档。

如果需要遍历数据库中的所有文档,请使用分页。通常,这是通过将范围FILTERLIMIT子句组合来实现的最佳方法:

FOR x IN docs
  FILTER x.offsetteableAttribute > @lastDocumentWithThisID
  LIMIT 200
    RETURN x

答案 1 :(得分:0)

我就是这样做的。您可以使用 more args 参数来指定,这样很容易做到。

查看源代码,您可以看到文档字符串说明要做什么

def AQLQuery(self, query, batchSize = 100, rawResults = False, bindVars = None, options = None, count = False, fullCount = False,
             json_encoder = None, **moreArgs):
    """Set rawResults = True if you want the query to return dictionnaries instead of Document objects.
    You can use **moreArgs to pass more arguments supported by the api, such as ttl=60 (time to live)"""
from pyArango.connection import *
conn = Connection(username=usr, password=pwd,arangoURL=url)# set this how ya need
db = conn['collectionName']#set this to the name of your collection
aql = """ for journal in journals.all():
    create_author_edge(journal)"""
doc = db.AQLQuery(aql,ttl=300)


这就是你需要做的!