Azure 函数和 Azure 存储 - 实体已存在 - nodeJS
Posted
技术标签:
【中文标题】Azure 函数和 Azure 存储 - 实体已存在 - nodeJS【英文标题】:Azure function and Azure storage - Entity already exists - nodeJS 【发布时间】:2021-08-15 17:44:03 【问题描述】:我知道在天蓝色存储表中插入实体的不同方法,但我找不到解决方案:
虽然我的函数是由队列触发的,但看起来有时尝试插入的实体已经存在于我的表中。
RowKey 是使用两个 4 位数字的数学随机生成的,我知道这可能并不理想,因为相同的数字可能会多次出现,但是您如何管理这种执行?
我使用输出绑定将数据发送到表,虽然这个绑定应该在终止函数进程之前尝试 5 次,但我只尝试了 1 次。 (我需要检查任何配置吗?)
是否有可能在发生错误时捕获错误并在重新提交之前将 rowkey 增加 1 或更多?如果是的话,你有什么可以让我效仿的例子吗?
使用输出绑定还是 JS sdk 都没有关系。
编辑: 我做了一些测试: 这有点工作,但它是合法的?
var azure = require('azure-storage');
var tableSvc = azure.createTableService(process.env.AzureWebJobsStorage);
module.exports = async function (context, myQueueItem)
context.log('javascript queue trigger function processed work item', myQueueItem);
var partkey = "Test"
var rokey = 39
try
context.bindings.outputTable = [];
context.bindings.outputTable.push(
PartitionKey: partkey,
RowKey: rokey,
Name: "Test"
);
finally
context.bindings.outputTable = [];
context.bindings.outputTable.push(
PartitionKey: partkey,
RowKey: rokey + 1,
Name: "Test"
);
现在存在 40 个,如果我再次运行,同样会在 finally 再次停止,因为在解决之前不会循环。
我是否应该在输入新实体之前查询表(具有大量条目)以检查键是否存在?这不会需要很长时间吗?
非常感谢您的帮助
编辑1: 我一直在阅读,我无法真正捕捉到执行时的输出绑定错误,所以我尝试使用 tableservice (node js sdk)
var azure = require('azure-storage');
var tableSvc = azure.createTableService(process.env.AzureWebJobsStorage);
module.exports = async function (context, myQueueItem)
context.log('JavaScript queue trigger function processed work item', myQueueItem);
var partkey = "Test"
var rokey = "39"
var a =
PartitionKey: partkey,
RowKey: rokey,
Name: "ZuzzuS!"
;
tableSvc.insertEntity('TestTable', a, function(error, result, response)
if(error)
// Insert table entity error
context.log.error("There was an error!")
else
// Insert table entity successfully
);
这应该给出错误,因为实体存在,而不是函数继续执行并完成而不做任何事情。
【问题讨论】:
【参考方案1】:关于这个问题,你可以使用insertOrMergeEntity
的方法。如果实体不存在,该方法将插入实体。否则,该方法将通过将新属性值合并到实体中来更新表中的实体。更多详情请参考here。
另外,如果你只是想做插入操作,请参考以下代码
var azure = require("azure-storage");
var accountName = "andyprivate";
var accountKey =
"h4pP1fe76m8hdksFW3TvkO6hgw09Mjue7yJOnULPI/g2eU8LGJ+a6k6SrU6dUkOU77waZfU8CacyVMlTWAUA5A==";
var tableSvc = azure.createTableService(accountName, accountKey);
var entGen = azure.TableUtilities.entityGenerator;
module.exports = async function (context, myQueueItem)
context.log(
"JavaScript queue trigger function processed work item",
myQueueItem
);
var partkey = "Test";
var rokey = 29;
var task =
PartitionKey: entGen.String(partkey),
RowKey: entGen.String(String(rokey)),
description: entGen.String("take out the trash"),
;
try
const r = await insert("test", task);
catch (error)
if (error.code == "EntityAlreadyExists")
context.log(error);
// insert
;
async function insert(tableName, entity)
return new Promise((resolve, reject) =>
tableSvc.insertEntity(tableName, entity, (error, result) =>
if (error)
reject(error);
else
resolve("OK");
);
);
【讨论】:
你好,谢谢你的建议,因为我不需要替换我不能使用 insertOrReplace,因为我们想保留一些正在发生的事情的记录。如果不存在,您的代码将插入实体,否则我猜会跳过它。我可以添加一些内容以使用不同的行键重试吗? @varVal 可以在代码中添加插入操作if (error.code == "EntityAlreadyExists") context.log(error);
@varVal 例如if (error.code == "EntityAlreadyExists") context.log(error); task = PartitionKey: entGen.String(partkey), RowKey: entGen.String(<new row key>), description: entGen.String("take out the trash"), ; await insert("test", task);
以上是关于Azure 函数和 Azure 存储 - 实体已存在 - nodeJS的主要内容,如果未能解决你的问题,请参考以下文章
Azure Functions - 使用 Azure Functions 的表存储触发器
使用 azure 数据工厂管道将 json 对象存储到 azure 表存储实体