Возникли проблемы с отловом исключения postgresql в сиквеле / ​​рубине - PullRequest
1 голос
/ 13 января 2011

У меня есть таблица postgresql, которая имеет какое-то уникальное ограничение.

У меня есть скрипт ruby, который обновит эту таблицу.Сценарий ruby ​​должен иметь возможность переключаться на UPDATE вместо INSERT, когда произошла ошибка такого типа:
PGError: ERROR: duplicate key value violates unique constraint

CMIIW, сиквел, похоже, не может перехватить это исключение ??

В любом случае,Пример кода ниже - это то, что я хотел бы видеть работающим, но, очевидно, нет:

@myarray.each do |x|
        fresh_ds = DB["INSERT INTO mytable (id, col_foo) values ('#{x}' ,'#{myhash[x]}')"] 
        result = fresh_ds.insert

        catch Sequel::Error do

            fresh_ds = DB["UPDATE mytable set col_foo = '#{myhash[x]} where id = #{x}"]
            result = fresh_ds.update

        end

end

Возможно, мой код ruby ​​неверен или я пропустил что-то, чего не знаю.
Любое решение?
Спасибо.

ОБНОВЛЕНИЕ: код ниже работает, ошибка обнаруживается при нарушении уникального ограничения.

@myarray.each do |x|
    begin
      # INSERT CODE
    rescue Sequel::Error
      # UPDATE CODE
    end

end

Ответы [ 2 ]

1 голос
/ 14 января 2011

Альтернативный путь для решения этой проблемы использует метод Sequel :: Model * find_or_create:

find_or_create (cond, &block)

Как поиск, но вызывает создание сданные условия, когда запись не существует.В отличие от find в том, что блок, используемый в этом методе, не передается для поиска, а вместо этого передается для создания, только если find не возвращает объект.

1 голос
/ 13 января 2011

Во-первых, try-catch в Ruby выглядит так :

begin
...
rescue ExceptionClass => ex
...
end

Другое дело, что вы должны использовать интерполяцию параметров Sequel вместо выполнения всего запроса вручную (в основном из-за внедрения SQL):

fresh_ds = DB["INSERT INTO mytable (id, col_foo) values (? ,?)", x, myhash[x]]

PS:

Как уже отмечали другие, есть и другие, возможно, лучшие способы выполнения "вставки или обновления". Обычно исключения предназначены для исключений, т. Е. Условий, которые обычно не должны возникать в ходе выполнения. Ваш случай больше относится к if сортировке, поэтому я сначала либо использовал бы SELECT, чтобы проверить, существует ли уже строка, либо, скорее, сначала попытался бы UPDATE и увидел количество измененных строк и выполнил INSERT, если ноль.

...