为什么ArangoDB(使用Python Arango)返回ERR 1600 ERROR_CURSOR_NOT_FOUN



问题

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

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

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

我有一个相对较小的数据集,journals-集合只有大约1300个文档。然而:这是超过1000,这是Web界面中的批量大小,但我不知道这是否相关。

问题是它引发了一个CursorNextError,并从数据库返回HTTP 404ERR 1600,这就是ERROR_CURSOR_NOT_FOUND错误:

当通过其id请求游标但找不到具有该id的游标时,将引发该游标。

深入了解原因

从ArangoDB Cursor Timeout和这个问题来看,我怀疑这是因为游标在数据库中的TTL已经过期,在python堆栈中可以看到这样的东西:

# 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驱动程序有问题,但我不知道。

(我添加了一个特性请求,在这里向.all()方法添加ttl参数。(

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


我没有代表来创建标签"python arango",所以如果有人能创建它并标记我的问题,那就太好了

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

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

一般来说,您应该避免一次从数据库中提取所有文档,因为这可能会引入其他缩放问题。您应该使用适当的AQL和由索引支持的FILTER语句(使用explain()重新验证(来获取所需的文档。

如果需要对数据库中的所有文档进行迭代,请使用分页。这通常是通过将范围FILTERLIMIT子句相结合来实现的最佳方式:

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

下面是我的操作方法。您可以用更多的参数指定param,这样做很容易。

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

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)

这就是你所需要做的!

最新更新