Ruby Sequel (SQlite3) ошибка «SELECT»

Я использую помощник ruby ​​для извлечения данных из базы данных SQLite3 с помощью sequel ORM. Вот код:

#!/usr/bin/env ruby
# encoding: UTF-8

require_relative 'greekdate'
require 'sequel'

module Pharmacy
    class Open
        def initialize
            db = Sequel.sqlite("../lib/drama.sql")
            @address = db[:addressbook]
            @ov = db[:overnight]
            @grday = GRDay::MDate.new
        end                         

        def display
            data = @address.first(id: get_id()) # ERROR HERE
            p data[:name]
        end

        private
        def get_id
            mod_date = @grday.get[:mod_date]
            @ov.each do |entry|
                return entry[:pharmacy_id] if entry[:date].to_s == mod_date
            end
        end
    end
end

Я вызываю метод display. Ошибка, которую я получаю:

/Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:91:in `initialize': SQLite3::SQLException: only a single result allowed for a SELECT that is part of an expression (Sequel::DatabaseError)
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:91:in `new'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:91:in `prepare'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sqlite3-1.3.7/lib/sqlite3/database.rb:263:in `query'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sequel-4.0.0/lib/sequel/adapters/sqlite.rb:179:in `block (2 levels) in _execute'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sequel-4.0.0/lib/sequel/database/logging.rb:33:in `log_yield'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sequel-4.0.0/lib/sequel/adapters/sqlite.rb:179:in `block in _execute'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sequel-4.0.0/lib/sequel/database/connecting.rb:229:in `block in synchronize'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sequel-4.0.0/lib/sequel/connection_pool/threaded.rb:104:in `hold'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sequel-4.0.0/lib/sequel/database/connecting.rb:229:in `synchronize'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sequel-4.0.0/lib/sequel/adapters/sqlite.rb:172:in `_execute'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sequel-4.0.0/lib/sequel/adapters/sqlite.rb:122:in `execute'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sequel-4.0.0/lib/sequel/dataset/actions.rb:794:in `execute'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sequel-4.0.0/lib/sequel/adapters/sqlite.rb:356:in `fetch_rows'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sequel-4.0.0/lib/sequel/dataset/actions.rb:144:in `each'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sequel-4.0.0/lib/sequel/dataset/actions.rb:584:in `single_record'
    from /Users/atma/.rvm/gems/ruby-1.9.3-p194/gems/sequel-4.0.0/lib/sequel/dataset/actions.rb:202:in `first'
    from test.rb:17:in `display'
    from test.rb:32:in `<main>'

Я не уверен, почему это. Сначала я подумал, что должен каким-то образом закрыть и снова открыть соединение, но ошибка говорит: «только один результат разрешен для SELECT, который является частью выражения», и я получал один результат. до вчерашнего дня я не вижу причин для получения 2 результатов, так как я вызываю table.first(id: X) .

Буду рад любым идеям и объяснениям :-)

Спасибо за ваше время,

PA


person patm    schedule 05.07.2013    source источник
comment
Вы должны указать свой код в вопросе, а не по ссылке. Он будет оставаться на НАМНОГО дольше. Что касается вашего вопроса, я считаю, что если в get_id() не будет найдено совпадений, метод вернет запрос db[:overnight] (потому что это поведение each). Вероятно, это ошибка в любом случае, и она может быть причиной вашей проблемы.   -  person Neil Slater    schedule 05.07.2013
comment
Обычно вы добавляете в запрос предложение .where, а не реализуете поиск в Ruby. Не могли бы вы включить свой код в вопрос?   -  person Neil Slater    schedule 05.07.2013
comment
Привет, Нил, я поставил код в вопрос, ты прав. Я использовал 2 файла SQLite3, один для тестирования и один для производства, я перепутал их, заканчивая пустыми записями. Я просто сделаю исключение, если БД пуста (идентификатор не возвращен), и все будет в порядке! Спасибо!   -  person patm    schedule 05.07.2013


Ответы (1)


Ваш метод get_id возвращает @ov, если ни одна запись в @ov не имеет заданной даты, так как это возвращаемое значение @ov.each. Вы, вероятно, хотите что-то вроде:

def display
    if id = get_id
      data = @address.first(id: id)
      p data[:name]
    end
end

private
def get_id
    mod_date = @grday.get[:mod_date]
    @ov.each do |entry|
        return entry[:pharmacy_id] if entry[:date].to_s == mod_date
    end
    nil
end

Обратите внимание, что display — плохой выбор для имени метода, так как Object#display уже определено ruby.

person Jeremy Evans    schedule 05.07.2013
comment
Правда, я переключил тот night_display, чтобы избежать глупых конфликтов. Я добавил предложение спасения, чтобы получить изящную ошибку и понятную ошибку, когда никакая запись не соответствует (чего в любом случае никогда не должно происходить). - person patm; 06.07.2013