UPSERT与ArangoDB的python-arango驱动程序

时间:2017-08-29 12:23:15

标签: python-3.x arangodb python-arango

我使用python-arango作为ArangoDB的驱动程序,并且它似乎不是UPSERT接口。

我打算用 python-arango 标记这个,但我没有足够的代表来创建新标记

我管理下面显示的功能,但我想知道是否有更好的方法可以做到这一点?

def upsert_document(collection, document, get_existing=False):
    """Upserts given document to a collection. Assumes the _key field is already set in the document dictionary."""
    try:
        # Add insert_time to document
        document.update(insert_time=datetime.now().timestamp())
        id_rev_key = collection.insert(document)
        return document if get_existing else id_rev_key
    except db_exception.DocumentInsertError as e:
        if e.error_code == 1210:
            # Key already exists in collection
            id_rev_key = collection.update(document)
            return collection.get(document.get('_key')) if get_existing else id_rev_key
    logging.error('Could not save document {}/{}'.format(collection.name, document.get('_key')))

注意在我的情况下,我确保所有文档都具有_key的值并且在插入之前,因此我可以假设这一点成立。如果其他人想要使用它,请相应地进行修改。

编辑:已移除使用_id字段,因为这不是问题的必要条件。

2 个答案:

答案 0 :(得分:1)

使用upsert的目的是从应用程序中保存数据库往返,而try/except的方法就不那么好了。

但是,暂时the ArangoDB HTTP-API尚不提供upsert,因此python-arango无法为您提供API。

您应该改用AQL query to upsert your document来实现:

UPSERT { name: "test" }
    INSERT { name: "test" }
    UPDATE { } IN users
LET opType = IS_NULL(OLD) ? "insert" : "update"
RETURN { _key: NEW._key, type: opType }

通过python-arango s db.aql.execute-interface

答案 1 :(得分:0)

难道你不能只使用这样的东西吗?

try:
    collection.update({'_key': xxx, ...})
except db_exception.DocumentInsertError as e:
    document.insert({'_key': xxx, ...})