【问题标题】:Cosmos Db - insert if not existsCosmos Db - 如果不存在则插入
【发布时间】:2020-09-01 04:12:56
【问题描述】:

亲爱的 Cosmos 会员,

我正在使用 CosmosTrigger 创建 Azure Function (Python):

  • 从 source_collection 读取数据
  • 将数据写入 target_collection(仅当文档不存在时)

为了实现“如果不存在则插入”功能,我使用唯一键“名称”配置了 target_collection。

例子:

  1. 写入 target_collection {"name": "John", "id": "1"} => 好的
  2. 写入 target_collection [{"name": "John", "id": "2"}, {"name": "Mary", "id": "3"}] => System.Private.CoreLib:执行函数时出现异常:Functions.CosmosTrigger。 Microsoft.Azure.DocumentDB.Core:系统中已存在具有指定 ID 的实体。

唯一键“name”:target_collection 中已存在“John”。所以 outdocs:func.Out[func.Document],outdocs.set() 返回冲突 409 并且“Mary”永远不会被写入 target_collection。

重要提示:当我将带有项目数组的 json 从数据资源管理器上传到 target_collection 时,所有冲突都会返回错误,但所有项目都会得到处理。 当我尝试从 Azure 函数编写它时,第一次冲突会引发错误,并且剩余的项目永远不会进入 target_collection。

我的问题:

  1. 有没有办法忽略引发的错误并使用 func.Out[func.Document].set() 处理整个项目数组?
  2. 或者,您能否告诉我在 Cosmos 中实现批量“如果不存在则插入”行为的最佳方法是什么?
def main(docs: func.DocumentList, outdocs: func.Out[func.Document]) -> str:
  compl_docs = func.DocumentList()

    compl_docs_dict = {
      "name": "John",
      "id": "2"
    }

    compl_docs.append(func.Document.from_dict(compl_docs_dict))

    compl_docs_dict = {
      "name": "Mary",
      "id": "3"
    }

    compl_docs.append(func.Document.from_dict(compl_docs_dict))

  outdocs.set(compl_docs)

【问题讨论】:

  • 你能分享一下你是如何写的代码吗? Cosmos DB 中的“如果不存在则插入”是 Upsert。问题是这不能解决你的问题。您的问题不是因为文档已经存在而创建失败,而是因为违反唯一键约束(因为name)而失败。在您的情况下,带有id 2 的文档与带有id 1 的文档是不同的文档,但它们具有相同的name,这违反了唯一密钥策略。
  • 也许我会改写 - 我想实现“如果文档存在则不插入”。我计划使用唯一键约束来自动处理重复项,但它会在上面抛出错误。我想在一个函数运行中发送 ["John", "Mary"]。如果集合中已经有“John”,则只写入“Mary”。目前我在“John”唯一键违规后出现错误,“Mary”从未得到处理。
  • Cosmos DB 输出绑定使用 Upsert,遗憾的是没有选项可以更改该行为。您唯一的选择似乎是独立维护 SDK 客户端(不使用输出绑定)。这样您就可以发出 Create(而不是 Upsert)并处理冲突(项目已经存在)。

标签: python azure-functions azure-cosmosdb bulkinsert conflict


【解决方案1】:

解决方案 这就是在 cosmos 中如何插入如果不存在:

  1. 在您的代码中创建 cosmos 客户端并使用 ExecuteProcedure 将文档从 azure 函数发送到 cosmos 过程
  2. 将存储过程添加到处理冲突的 cosmos 集合中。您可以从 Microsoft 找到 bulkUpsert_v_2 并对其进行修改,以便在发生冲突 409 时,不会向 cosmos 写入任何内容。

【讨论】:

    猜你喜欢
    • 2018-09-17
    • 2014-06-11
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    相关资源
    最近更新 更多