You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby循环调用分页API时哈希更新及offset参数失效问题

Ruby分页拉取接口数据构建哈希映射问题修复

已更新采用getEntitlementList()方法实现相关逻辑。本人是Ruby初学者,尝试分步拉取数据并更新哈希结构,此前关于Ruby拆分与循环的问题已解决。


遇到的核心问题

  • 分页参数失效:按步长250依次设置offset参数(取值依次为0、250、500直至3000),但接口每次返回的响应完全相同,未返回不同分页的数据。
  • 哈希结果不全:目标接口共有3000条数据,单次调用最多拉取250条,预期每次拉取到新分页数据时更新同一个哈希对象,最终得到包含所有条目的哈希,但实际最终哈希仅保留最后一次拉取的250条数据。此前已尝试使用entitlementHash.update、entitlementHash.store、entitlementHash.merge方法实现,均未达到预期效果。

接口规则说明

  • limit:整数类型,指定单次API调用返回的最大记录数,未指定时使用默认值,单页最大支持返回250条记录。
  • offset:整数类型,指定从集合起始位置开始的第一条结果的偏移量,offset基于记录数而非页数计算,索引从0开始。例如offset=0、limit=20将返回0-19号记录,offset=1、limit=20将返回1-20号记录,取值范围为0到最后一条记录的索引之间。

最终需要构建displayableName(大写格式)与id一一对应的完整哈希映射表。


现有代码

接口请求方法

def getEntitlementList(url,header,source,limit,offset)
  # 该方法用于拉取指定数据源的现有权限列表
  # 该列表用于构建displayableName与Id映射的哈希表
  # 返回哈希映射结构
  uri = URI.parse( "#{url}/cc/api/entitlement/list?limit=#{limit}&offset=#{offset}&CISApplicationId=#{source}" )
  puts uri
  http = Net::HTTP.new( uri.host, uri.port )
  http.use_ssl = true
  request = Net::HTTP::Get.new( uri.request_uri, header )
  response = http.request( request )
  case response
  when Net::HTTPSuccess
    responseBody = JSON.parse(response.body)
  when Net::HTTPUnauthorized
    puts "#{source} Entitlements Hash Map creation is a Failure!"
    puts "Error: Unauthorized."
  when Net::HTTPServerError
    puts "#{source} Entitlements Hash Map creation is a Failure!"
    puts "Error: Server Error."
  else
    puts "#{source} Entitlements Hash Map creation is a Failure!"
    puts "Error: #{response.code}"
  end
  return responseBody
end

分页拉取逻辑

limit = 250
entitlementHash = Hash.new

(0..3000).step(250) do |offset|
  responseBody = getEntitlementList(url,header,source,limit,offset)
  count = responseBody['count']
  entitlementList = responseBody['items']

  entitlementList.each {|a| entitlementHash["#{a['displayableName'].upcase()}"] = 
  a['id']}

  puts "updated entitlementHash size: #{entitlementHash.size}"
end
return entitlementHash

问题根因与修复方案

1. 分页始终返回第一页数据

核心问题是构造请求URI时,参数分隔符错误使用了HTML转义字符&,Ruby的URI解析不会自动将该转义符转换为普通的&,导致服务端无法正确识别offset和CISApplicationId参数,始终使用默认offset=0返回第一页数据。
修复方式:将URI拼接逻辑中的所有&替换为普通&即可。

2. 哈希仅保留250条数据

这个问题是分页失效的连锁反应:每次请求拿到的都是第一页的250条重复数据,无论用哪种哈希写入方法,都是对相同的250个key重复赋值,最终哈希大小自然停留在250。修复分页参数问题后,现有逐行写入哈希的逻辑本身完全可用,不需要额外替换merge/update类方法。

额外优化

现有逻辑写死循环到offset=3000,灵活性差,建议根据接口返回的总记录数count动态判断循环终止条件,同时增加重名校验,避免不同条目displayableName大写后重复导致ID被覆盖。


修复后完整参考代码

def getEntitlementList(url,header,source,limit,offset)
  # 替换&为普通&,修复参数解析问题
  uri = URI.parse( "#{url}/cc/api/entitlement/list?limit=#{limit}&offset=#{offset}&CISApplicationId=#{source}" )
  puts uri
  http = Net::HTTP.new( uri.host, uri.port )
  http.use_ssl = true
  request = Net::HTTP::Get.new( uri.request_uri, header )
  response = http.request( request )
  responseBody = nil
  case response
  when Net::HTTPSuccess
    responseBody = JSON.parse(response.body)
  when Net::HTTPUnauthorized
    puts "#{source} Entitlements Hash Map creation is a Failure!"
    puts "Error: Unauthorized."
  when Net::HTTPServerError
    puts "#{source} Entitlements Hash Map creation is a Failure!"
    puts "Error: Server Error."
  else
    puts "#{source} Entitlements Hash Map creation is a Failure!"
    puts "Error: #{response.code}"
  end
  return responseBody
end

# 分页拉取逻辑
limit = 250
entitlementHash = {}
offset = 0

loop do
  responseBody = getEntitlementList(url, header, source, limit, offset)
  break unless responseBody.is_a?(Hash) && responseBody['items'].is_a?(Array)
  
  total_count = responseBody['count'].to_i
  entitlementList = responseBody['items']
  
  entitlementList.each do |item|
    name_key = item['displayableName'].to_s.upcase
    # 重名告警,避免数据覆盖
    if entitlementHash.key?(name_key)
      puts "警告:重名权限#{name_key},原ID:#{entitlementHash[name_key]},新ID:#{item['id']}"
    end
    entitlementHash[name_key] = item['id']
  end
  
  puts "已拉取offset=#{offset}页数据,当前哈希总条目数:#{entitlementHash.size}"
  offset += limit
  # 拉取完全部数据后终止循环
  break if offset >= total_count
end

return entitlementHash

内容的提问来源于stack exchange,提问作者born2Learn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 05:48:34