ServiceNow Table API 返回重复项/不返回所有记录

ServiceNow Table API returning duplicates / not returning all records

我正在尝试将 ALL 数据从 ServiceNow CMDB 数据 table 中提取到我自己的 SQL 数据库中。当数据在需要与新 SN 实施同步的客户遗留系统中维护时,我计划使用它进行自动更新。

我们的 SN 环境有很多域、很多客户等。这转化为大量数据。由于数据太大,尝试在单个 API 调用中提取所有记录自然会导致超时异常。网上API建议对数据进行批处理,我是这样实现的:

        ...
        var offset = 0;

        while (true)
        {
            var requestUrl = string.Format("{0}/api/now/table/cmdb_ci_vm_instance?sysparm_offset={1}&sysparm_limit={2}&sysparm_exclude_reference_link=true", url, offset, batchSize);
            var result = ApiRequest.Get(new Uri(requestUrl), _credential, null, out response);
            if (result == HttpStatusCode.OK)
            {
                var virtualmachineRo = JsonConvert.DeserializeObject<VirtualMachineRootObject>(response);

                if (virtualmachineRo.result.Count < batchSize)
                {
                    virtualmachines.AddRange(virtualmachineRo.result);
                    break;
                }

                virtualmachines.AddRange(virtualmachineRo.result);
                offset += virtualmachineRo.result.Count;
            }
            else
            {
                break;
            }
        }
        ....

我使用过不同的批量大小,结果不同。根据我击中的 table,有时我会得到重复项,有时我不会,有时我会得到不同的重复项。在几乎所有情况下,当我 DO 得到一个副本时,副本会替换流中的有效记录,这意味着我是 'missing' 一个有效记录。

我已通过查看来自 serviceNow 的原始数据流并查看重复项,并验证 ServiceNow 中是否存在未显示在我的流中的记录(通常在我尝​​试创建时发现)来确认这一点丢失的记录和 SN 响应 "ignored - no field changed" 表明该记录已经存在。)

我试图搜索并找到任何有类似问题的人,但没有找到任何东西。在直接用 SN 开票之前,我希望看看我的代码是否有什么地方做错了,或者这是否是我所期望的 - 一个与平台相关的错误。

您可以尝试在主键(sys_id)上添加显式排序以确保每个批处理查询。您可以通过添加 URL 参数 sysparm_query=ORDERBYsys_id

来完成此操作

您的 URL 看起来像: "{0}/api/now/table/cmdb_ci_vm_instance?sysparm_offset={1}&sysparm_limit={2}&sysparm_exclude_reference_link=true&sysparm_query=ORDERBYsys_id"

所以这几乎可以肯定是他们 API 中与服务帐户访问相关的错误。这是我所做的,以及我认为正在发生的事情(以及我的工作!)

在尝试了一些不同的逻辑之后,我遇到了以下情况:

{0}/api/now/table/cmdb_ci_vm_instance?sysparm_offset=0&sysparm_limit=750&sysparm_exclude_reference_link=true&sysparm_query=ORDERBYsys_id
2016-08-19 12:46:15,277 [INFO ] Returned Records Count: 750

{0}/api/now/table/cmdb_ci_vm_instance?sysparm_offset=750&sysparm_limit=750&sysparm_exclude_reference_link=true&sysparm_query=ORDERBYsys_id
2016-08-19 12:46:28,243 [INFO ] Returned Records Count: 746

注意第二遍我要了750条记录,结果只得到746条(相差4.)其他批次照常继续return750条,最后我正好结束了检索到的 5200 多条记录中有 4 条是重复的。因为第二遍 returning 小于我要求的 750,我的代码被破坏了,因为它认为数据是完整的...

为了解决这个问题(最初)我对上面的代码做了以下操作:

if (virtualmachineRo.result.Count == 0)
{
    //AddRange(virtualmachineRo.result);
    break;
}

我不再相信仅仅因为 returned 的记录数少于 sysparm_limit 我检索了所有记录。

看起来当从数据库中提取数据时,一个单独的进程会根据您的权限过滤数据。因此,第二批删除了 4 条记录 - 但数据库不知道更好......所以在下一次通过 746 调用的实际计数 return 增加我的偏移量时,它 returns同一个数据集,该批次的后4条记录被复制为下一页数据中的前4条记录。 (在数据流中确认-排序数据时,导致重复出现在不同的地方,并且不同的记录也是基于批次重复的size/order!)

我不敢相信这是预期的行为,而且 Wiki 中肯定没有记录。无论哪种方式,解决方法对于任何 运行 的人来说都很简单:即使计数 returned 小于批量大小,您也必须继续提取数据并继续直到 0 条记录被 returned .然后你必须用一些简单的东西过滤掉重复项:

yourrecords.GroupBy(x => x.sys_id).Select(x => x.First()).ToList();

问题是'solved.'