簡體   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