2016-11-25 51 views
0

我試圖解析一個額外的鍵,我已經解析了一段時間的現有JSON,但最近我們添加了一個新的鍵「metric_details」,分開單獨的區域,這包含2個鍵以及「performance_score」,和「compliance_score」。現在,我已經能夠毫無問題地解析這個問題,但卻無法弄清楚如何將metric_details拉出來並將分數導出到我的RDS中。Ruby JSON解析「子鍵」?

解析代碼:

states = %w(CA TX) 
results_warehouses = states 
creds = User_creds 

data_to_write = [] 
results_warehouses.each do |code| 

    dashboard = "https://sample.website.com/states/scorecard.json?state_id=#{code}" 
    puts "Pulling from #{dashboard}" 

    begin 
    data = HTTParty.get(dashboard, :basic_auth=> {:username => creds.public.text, :password => creds.private.text}) 
    rescue 
    puts "Could not fetch data for #{code}. Skipping..." 
    next 
    end 

    types = %w(pack ship) 
    types.each do |type| 

    metric = data[type] 
    next if metric.nil? 
    metric.sort.each do |key| 
     state_id    = key['state_id'] 
     raw_date    = key['date'].to_date 
     # Can't figure how to parse this metric_details   = key['metric_details'] 
     performance_score  = key['performance_score'] 
     audit_compliance_score = key['compliance_score'] 

     data_to_write << "('#{state_id.to_s}', 
         '#{raw_date.to_s}', 
         '#{type.to_s}', 
         '#{metric_details.to_s}', 
         '#{performance_score.to_s}', 
         '#{compliance_score.to_s}')" 
     puts data_to_write 
    end 
    end 

    unless data_to_write.empty? 
    puts 'Inserting data' 
    db_conn = DatabaseConnect.new 
    db_client = db_conn.connect_mysql 
    ins = "INSERT IGNORE INTO `data`.`scoring` VALUES #{data_to_write.join(',')}" 
    db_client.query(ins) 
    end 
    db_conn.disconnect 
    puts 'Completed.' 
end 

puts 'All done!' 

而且,這裏是我拉開JSON,這沒有問題,直到我試圖抓住個別指標細節

"pack":[ 
{ 
"state_id":"CA", 
"total_score":90, 
"compliance_score":100, 
"performance_score":80, 
"date":"2016-11-24T00:00:00.000-08:00", 
"metric_details":{ 
"Damages":{ 
"performance_score":91, 
"compliance_score":100 
}, 
"Error Indicators":{ 
"performance_score":100, 
"compliance_score":"N/A" 
}, 
"Unverified":{ 
"performance_score":75, 
"compliance_score":100 
}, 
"Pack Miss":{ 
"performance_score":54, 
"ompliance_score":100 
} 
} 
} 
], 

而我的表格結構相當簡單:

,基本上想這樣的格式:

CA,2016年11月25日,包,損害賠償,75,100

STATE_ID,raw_date,類型,metric_details,performance_score,compliance_score

謝謝你的幫助!

更新時間:

states = %w(CA TX) 
results_warehouses = states 
creds = User_creds 

data_to_write = [] 
results_warehouses.each do |code| 

    dashboard = "https://sample.website.com/states/scorecard.json?state_id=#{code}" 
    puts "Pulling from #{dashboard}" 

    begin 
    data = HTTParty.get(dashboard, :basic_auth=> {:username => creds.public.text, :password => creds.private.text}) 
    rescue 
    puts "Could not fetch data for #{code}. Skipping..." 
    next 
    end 

    types = %w(pack ship) 
    types.each do |type| 

    metric = data[type] 
    next if metric.nil? 
    metric.sort.each do |key| 
     state_id    = key['state)ud'] 
     raw_date    = key['date'].to_date 
     hash     = key['metric_details'] 
     damages     = hash['Damages'] 
     performance_score  = damages['performance_score'] 
     audit_compliance_score = damages['compliance_score'] 

     data_to_write << "('#{state_id.to_s}', 
         '#{raw_date.to_s}', 
         '#{type.to_s}', 
         '#{metric_details.to_s}', 
         '#{performance_score.to_s}', 
         '#{audit_compliance_score.to_s}')" 
     puts data_to_write 
    end 
    end 

    unless data_to_write.empty? 
    puts 'Inserting data' 
    db_conn = DatabaseConnect.new 
    db_client = db_conn.connect_mysql 
    ins = "INSERT IGNORE INTO `data`.`scoring` VALUES #{data_to_write.join(',')}" 
    db_client.query(ins) 
    end 
    db_conn.disconnect 
    puts 'Completed.' 
end 

puts 'All done!' 

回答

2

key['metric_details']返回哈希:

{ 
    "Damages":{ 
    "performance_score":91, 
    "compliance_score":100 
    }, 
    "Error Indicators": { 
    "performance_score":100, 
    "compliance_score":"N/A" 
    }, 
    ... 
    ... 
} 

所以,你需要查找在哈希信息:

hash = key['metric_details'] 
damages = hash['Damages'] 
performance_score = damages['performance_score'] 
compliance_score = damgages['compliance_score'] 

這裏是一個完整的例子:

require 'json' 

data = %Q{ 
{"pack":[ 
{ 
"state_id": "CA", 
"total_score":90, 
"compliance_score":100, 
"performance_score":80, 
"date":"2016-11-24T00:00:00.000-08:00", 
"metric_details":{ 
"Damages":{ 
"performance_score":91, 
"compliance_score":100 
}, 
"Error Indicators":{ 
"performance_score":100, 
"compliance_score":"N/A" 
}, 
"Unverified":{ 
"performance_score":75, 
"compliance_score":100 
}, 
"Pack Miss":{ 
"performance_score":54, 
"ompliance_score":100 
} 
} 
} 
] 

} 
} 

data = JSON.parse data 
data_to_write = "" 

types = %w(pack ship) 
types.each do |type| 
    metric = data[type] 
    next if metric.nil? 

    metric.sort.each do |hash| 
    state_id    = hash['state_id'] 
    raw_date    = hash['date'] 
    # Can't figure how to parse this metric_details   = key['metric_details'] 
    #performance_score  = key['performance_score'] 
    #audit_compliance_score = key['compliance_score'] 
    metric_details = hash['metric_details'] 
    damages_hash = metric_details['Damages'] 
    performance_score = damages_hash['performance_score'] 
    compliance_score = damages_hash['compliance_score'] 

    data_to_write << "('#{state_id}', 
         '#{raw_date}', 
         '#{type}', 
         '#{performance_score}', 
         '#{compliance_score}')" 
    puts data_to_write 
    end 
end 

--output:-- 
('CA', 
         '2016-11-24T00:00:00.000-08:00', 
         'pack', 
         '91', 
         '100') 
+0

這可以在初始循環中執行嗎? next metric.nil? metric.sort.each do | key | warehouse_id =鍵[ 'warehouse_id'] raw_date =鍵[ '日期']。TO_DATE 散列=鍵[ 'metric_details'] 損害=散列[ '損傷'] performance_score =損害[ 'performance_score'] audit_compliance_score =損害['compliance_score'] – Spartacus38

+1

@ Spartacus38,我認爲您可以將該代碼放在您的評論的位置,並刪除評論下的兩行。 – 7stud

+0

lib/script/metric_details.rb:38:在中的塊(3級)中:來自lib/script/metric_details的main:Object(NameError) 的未定義局部變量或方法'metric_details'。 rb:27:在'每個'中 from lib/script/metric_details.rb:27:在' from lib/script/metric_details.rb:23:in'each ' from lib/script/metric_details.rb:23:in'block in ' from lib/script/metric_details.rb:7:in'each' from lib/script/metric_details.rb: 7:在'' – Spartacus38