繁体   English   中英

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

[英]Why does ArangoDB (using Python-Arango) return ERR 1600 ERROR_CURSOR_NOT_FOUND?

问题

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

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

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

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

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

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

对原因的见解

ArangoDB Cursor Timeout这个 issue ,我怀疑这是因为游标的 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 驱动程序,但我不知道。

(我已经添加了一个功能请求,将 ttl-param 添加到.all() -method here 。)

关于为什么会发生这种情况的任何见解?


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

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

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

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

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

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

所以这就是我是如何做到的。 您可以使用 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)


这就是你需要做的一切!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM