首页 > 解决方案 > Ruby on Rails:尝试从 API 获取 JSON 数据并保存到 Postgres 数据库 - rake 中止!TypeError:没有将字符串隐式转换为整数

问题描述

我正在使用 Ruby on Rails 并尝试从公共 API 获取 JSON 数据并保存到 Postgres 数据库。

当我运行 rake db:seed 时,我收到以下错误:

rake aborted!
TypeError: no implicit conversion of String into Integer
/db/seeds.rb:21:in `[]'
/db/seeds.rb:21:in `properties'
/db/seeds.rb:48:in `<top (required)>'
Tasks: TOP => db:seed
(See full trace by running task with --trace)

作为参考,第 21 行是:

json["data"].map do |property|

第 48 行是调用该方法的位置:

properties

这是 JSON 数组中的第一项,可让您了解我要映射的内容。

[
  {
    "PublicationDate": "26/10/2018",
    "PropertyNumber": 2195606,
    "County": "LAOIS",
    "LocalAuthority": "LAOIS COUNTY COUNCIL",
    "Valuation": 70600.0,
    "Category": "RETAIL (SHOPS)",
    "Uses": "SUPERMARKET 2 [500-2500 SQ. M.], -",
    "Address1": "36-42A/1 POUND STREET",
    "Address2": "RATHDOWNEY",
    "Address3": "CO. LAOIS",
    "Address4": "",
    "Address5": "",
    "CarPark": 0,
    "Xitm": 628016.65,
    "Yitm": 678231.8,
    "ValuationReport": [
      {
        "Level": "0      ",
        "FloorUse": "SUPERMARKET",
        "Area": 964.62,
        "NavPerM2": 60.0000,
        "Nav": 57877.200000
      },
      {
        "Level": "0",
        "FloorUse": "OFF LICENCE",
        "Area": 1.00,
        "NavPerM2": 8681.5800,
        "Nav": 8681.580000
      },
      {
        "Level": "0",
        "FloorUse": "FIT-OUT ALLOWANCE",
        "Area": 1.00,
        "NavPerM2": 4051.4000,
        "Nav": 4051.400000
      }
    ]
  },

我的数据库架构遵循 JSON 结构,但不完全一致(我不确定这是否会导致问题):

create_table "properties", force: :cascade do |t|
    t.bigint "user_id"
    t.string "publication_date"
    t.string "property_number"
    t.string "county"
    t.string "local_authority"
    t.string "valuation"
    t.string "category"
    t.string "uses"
    t.string "address_1"
    t.string "address_2"
    t.string "address_3"
    t.string "address_4"
    t.string "address_5"
    t.string "car_park"
    t.string "xitm"
    t.string "yitm"
    t.string "valuation_report"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["user_id"], name: "index_properties_on_user_id"
  end 

这是我的seeds.rb 文件:

require 'rest-client'

# Define Method
def properties

    response = RestClient.get('https://api.valoff.ie/api/Property/GetProperties?Fields=*&LocalAuthority=LAOIS%20COUNTY%20COUNCIL&CategorySelected=RETAIL%20(SHOPS)&Format=csv&Download=false')

    json = JSON.parse response
    
    if !json.nil?
        json["data"].map do |property|
            Property.create(
                publication_date: "#{PublicationDate}",
                property_number: "#{PropertyNumber}",
                county: "#{County}",
                local_authority: "#{LocalAuthority}",
                valuation: "#{Valuation}",
                category: "#{Category}",
                uses: "#{Uses}",
                address_1: "#{Address1}",
                address_2: "#{Address2}",
                address_3: "#{Address3}",
                address_4: "#{Address4}",
                address_5: "#{Address5}",
                car_park: "#{CarPark}",
                xitm: "#{Xitm}",
                yitm: "#{Yitm}",
                valuation_report: "#{ValuationReport}"
            )
        end
    else
        puts "Error seeding properties."
    end

end

# Call Method
properties

当我运行 rake db:seed 时,我收到以下错误:

rake aborted!
TypeError: no implicit conversion of String into Integer
/db/seeds.rb:21:in `[]'
/db/seeds.rb:21:in `properties'
/db/seeds.rb:48:in `<top (required)>'
Tasks: TOP => db:seed
(See full trace by running task with --trace)

作为参考,第 21 行是:

json["data"].map do |property|

第 48 行是调用该方法的位置:

properties

任何帮助将不胜感激,谢谢

标签: ruby-on-railsjsonrubypostgresqlapi

解决方案


总结各种评论中的建议,jsonArray在解析 JSON 之后。数组索引是整数,因此json["data"]结果为TypeError. 其次,返回的 JSON 记录没有data字段。您可以简单地遍历结果数组并创建您的记录,如下所示:

def properties
  response = RestClient.get('https://api.valoff.ie/api/Property/GetProperties?Fields=*&LocalAuthority=LAOIS%20COUNTY%20COUNCIL&CategorySelected=RETAIL%20(SHOPS)&Format=csv&Download=false')

  json = JSON.parse(response)

  json.each do |property|
    puts "Creating property #{property['PropertyNumber']}"
    Property.create!(
      publication_date: property['PublicationDate'],
      property_number: property['PropertyNumber'],
      county: property['County'],
      local_authority: property['LocalAuthority'],
      valuation_report: property['ValuationReport']
      # ... remaining fields omitted for brevity
    )
  end
end

您实际上不需要.nil?检查您的原始文件,因为RestClient对于 200-2007 以外的任何 HTTP 响应代码都会引发错误。同样,JSON.parse如果响应不是有效的 JSON,将引发错误。

结果:

$ rails db:seed
Creating property 1555903
Creating property 1556133
Creating property 1556998
Creating property 1556516
Creating property 1557007
...

推荐阅读