【问题标题】:Why does ArangoDB (using Python-Arango) return ERR 1600 ERROR_CURSOR_NOT_FOUND?为什么 ArangoDB(使用 Python-Arango)返回 ERR 1600 ERROR_CURSOR_NOT_FOUND?
【发布时间】:2018-07-31 12:49:10
【问题描述】:

问题

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

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

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

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

问题是它引发了CursorNextError,并从数据库中返回HTTP 404ERR 1600,也就是ERROR_CURSOR_NOT_FOUND error

当通过其 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()-method here。)

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


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

【问题讨论】:

    标签: python arangodb


    【解决方案1】:

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

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

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

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

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

    【讨论】:

      【解决方案2】:

      这就是我的做法。您可以指定更多的 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)
      
      
      

      这就是你需要做的!

      【讨论】:

        猜你喜欢
        • 2021-08-24
        • 1970-01-01
        • 2018-02-06
        • 1970-01-01
        • 2018-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-31
        相关资源
        最近更新 更多