Ruby Sequel MySQL 插入错误

Ruby Sequel MySQL Insert Error

我正在学习 Ruby 并且我正在使用 Sequel gem 来处理我的模型。但我一直 运行ning 陷入一个我似乎无法追查的错误。没有意义的是它在插入时失败,因为我要插入的 table 中不存在字段。但是,我并没有尝试使用不存在的字段。

这是我的错误:

0
{:id=>5, :name=>"barcelona"} : {:id=>4, :name=>"berlin"}
/Users/username/.rvm/gems/ruby-2.2.0/gems/sequel-4.20.0/lib/sequel/adapters/mysql.rb:175:in `query': Mysql::Error: Unknown column 'name' in 'field list' (Sequel::DatabaseError)
    from /Users/username/.rvm/gems/ruby-2.2.0/gems/sequel-4.20.0/lib/sequel/adapters/mysql.rb:175:in `block in _execute'
    from /Users/username/.rvm/gems/ruby-2.2.0/gems/sequel-4.20.0/lib/sequel/database/logging.rb:33:in `log_yield'
    from /Users/username/.rvm/gems/ruby-2.2.0/gems/sequel-4.20.0/lib/sequel/adapters/mysql.rb:175:in `_execute'
    from /Users/username/.rvm/gems/ruby-2.2.0/gems/sequel-4.20.0/lib/sequel/adapters/shared/mysql_prepared_statements.rb:34:in `block in execute'
    from /Users/username/.rvm/gems/ruby-2.2.0/gems/sequel-4.20.0/lib/sequel/database/connecting.rb:250:in `block in synchronize'
    from /Users/username/.rvm/gems/ruby-2.2.0/gems/sequel-4.20.0/lib/sequel/connection_pool/threaded.rb:98:in `hold'
    from /Users/username/.rvm/gems/ruby-2.2.0/gems/sequel-4.20.0/lib/sequel/database/connecting.rb:250:in `synchronize'
    from /Users/username/.rvm/gems/ruby-2.2.0/gems/sequel-4.20.0/lib/sequel/adapters/shared/mysql_prepared_statements.rb:34:in `execute'
    from /Users/username/.rvm/gems/ruby-2.2.0/gems/sequel-4.20.0/lib/sequel/adapters/mysql.rb:160:in `execute_insert'
    from /Users/username/.rvm/gems/ruby-2.2.0/gems/sequel-4.20.0/lib/sequel/dataset/actions.rb:927:in `execute_insert'
    from /Users/username/.rvm/gems/ruby-2.2.0/gems/sequel-4.20.0/lib/sequel/dataset/actions.rb:336:in `insert'
    from travellingAmerican.rb:70:in `addDist'
    from travellingAmerican.rb:64:in `block (2 levels) in addLocations'
    from travellingAmerican.rb:61:in `each'
    from travellingAmerican.rb:61:in `block in addLocations'
    from travellingAmerican.rb:58:in `each'
    from travellingAmerican.rb:58:in `addLocations'
    from travellingAmerican.rb:93:in `<main>'

这里是models.rb:

#Database
require 'sequel'

def create
    DB.create_table(:locations) do
        primary_key :id
        String :name, :unique=>true
    end

    DB.create_table(:distances) do
        primary_key :id
        foreign_key :to, :locations
        foreign_key :from, :locations
        Float :miles, :default=>-1
        TrueClass :valid, :default=>0
        unique [:to, :from]
    end

end

def drop
    begin
        DB.drop_table(:distances)
    rescue
        puts "Couldn't drop Distances"
    end

    begin
        DB.drop_table(:locations)
    rescue
        puts "Couldn't drop locations"
    end

end


DB = Sequel.connect(:adapter=>'mysql', :host=>'myHost', :user=>'myUser', :password=>'myPass', :database=>'myDB')

if __FILE__ == $PROGRAM_NAME
    puts "Will Execute"
    drop
    create
    puts "Done Executing"
end

现在错误所在的文件,travellingAmerican.rb:

#Traveling American
require './models.rb'
require 'json'




def urlCreator(cities)
    urls = []
    rootUrl = "https://maps.googleapis.com/maps/api/distancematrix/json?"
    origin = "origins="
    dest = "destinations="
    key = "myApiKey"

    cities.each do |city|
            city = city.gsub(/[" "]/, '+')
            newOrigin = origin + city + "|"
            newDest = dest
        cities.each do |inCity|
            newDest += inCity + "|"

        end
        newUrl = rootUrl + newOrigin + "&" + newDest + "&" + key
        urls.push(newUrl)
    end
    urls
end

def processFile(file)
    cities = []


    File.readlines(file).each do |line|
        line = line.strip

        if line.count(",") == 1
            line = line.split()
        else
            cities.push(line)
        end
    end
    return cities
end

def addLocations(cities)

    cities.each do |city|
        begin
            DB[:locations].insert(:name => city.downcase)
        rescue Sequel::UniqueConstraintViolation
            puts "Duplicate, not added"
        end
    end

    allLocs = DB[:locations].where(:name => cities).order(:name).all
    #if you puts allLocs it works beautifully

    for i in 0...allLocs.length
        puts i
        toLoc = allLocs[i]
        for j in (i+1)...allLocs.length
            fromLoc = allLocs[j]
            puts toLoc.to_s + " : " + fromLoc.to_s 
            #If you comment out the line below everything runs fine, minus the insertion obviously
            addDist(toLoc, fromLoc)
        end
    end
end

def addDist(tos, froms)
    #the line with the error
    DB[:distances].insert(:to=>tos, :from=>froms)
end

if __FILE__ == $PROGRAM_NAME
    popSize = -1
    file = ""

    count = 0
    ARGV.each do|arg|
        if count == 0
            popSize = arg.to_i
        else
            file = arg
        end

        count += 1
    end

    if popSize == -1 or file == ""
         abort("Usage: ruby travellingAmerican.rb popSize cityList")
    end

    cities = processFile(file)
    addLocations(cities)

    puts urlCreator(cities)

end

如果您想 运行 在您自己的机器上执行此操作,最后是 cities.csv:

San Diego
Munich
Paris
Berlin
Barcelona
Monte Carlo
Cinque Terre
Turin 
Milan
Florence
Rome
Venice

要运行 在你自己的机器上执行 ruby travellingAmerican.rb 1000 cities.csv in a shell.

希望我已经为大家提供了足够的信息!感谢观看。

我检测到一些问题:

在这里添加小写的城市:

    cities.each do |city|
        begin
            DB[:locations].insert(:name => city.downcase)
        rescue Sequel::UniqueConstraintViolation
            puts "Duplicate, not added"
        end
    end

您在哈希中读取它们:

    allLocs = DB[:locations].where(:name => cities).order(:name).all

条件是没有小写!所以你得不到结果。 你可以这样做:

allLocs = DB[:locations].where(:name => cities.map(&:downcase)).order(:name).all

以后用

        addDist(toLoc, fromLoc)

toLocfromLoc 都是哈希值,但应该是 table 个城市的关键。

这应该有效:

        addDist(toLoc[:id], fromLoc[:id])

作为替代方案,您可以调整 addDist

中的插入
DB[:distances].insert(:to=>tos[:id], :from=>froms[:id])

for 的用法与 ruby 不同。我会直接使用 Sequel::Dataset#each:

selection = DB[:locations].where(:name => cities.map(&:downcase)).order(:name)
selection.each{|toLoc|
  selection.each{|fromLoc|
        puts toLoc.to_s + " : " + fromLoc.to_s 
        #If you comment out the line below everything runs fine, minus the insertion obviously
        addDist(toLoc[:id], fromLoc[:id])
   }
}

(如果这里确实需要where和order方法,你可以讨论)