UPSERT 与 python-ArangoDB 的 arango 驱动程序

UPSERT with python-arango driver for ArangoDB

我正在使用 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 字段的使用,因为这对问题来说不是必需的。

你就不能用这样的东西吗?

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

使用 upsert 的要点是保存应用程序的数据库往返,这是 try/except 方法不太好的原因。

但是,目前 the ArangoDB HTTP-API 不提供更新插入,因此 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

如果您使用的是 python-arango,您应该能够执行以下操作:

collection.insert({'_key': xxx, ...}, overwrite_mode='replace')

collection.insert({'_key': xxx, ...}, overwrite_mode='update')
 :param overwrite_mode: Overwrite behavior used when the document key
            exists already. Allowed values are "replace" (replace-insert) or
            "update" (update-insert). Implicitly sets the value of parameter
            **overwrite**.