Почему `execute` возвращается к оболочке, а не отправляет SQL напрямую на мой сервер Postgres? - PullRequest
1 голос
/ 15 сентября 2011

У меня есть миграция, которая использует execute для отправки необработанного SQL-кода в бэкэнд Postgres.

class TestExecuteMethod < ActiveRecord::Migration
  def self.up
    execute ('SELECT 1;')
  end

  def self.down
  end
end

Вместо того, чтобы идти в мою базу данных, кажется, execute собирается в оболочку:

** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:migrate
==  TestExecuteMethod: migrating ==============================================

++ executing: SELECT 1;
sh: SELECT: command not found
++   [FAIL]
==  TestExecuteMethod: migrated (0.0041s) =====================================

** Invoke db:schema:dump (first_time)
** Invoke environment 
** Execute db:schema:dump

Но, когда я вместо этого

ActiveRecord::Base.connection.execute(sql)

Это работает, как ожидалось.

Почему это?

Я использую Rails 3.0.9 и самоцвет pg.

Ответы [ 2 ]

1 голос
/ 17 сентября 2011

Добавьте это к вашей миграции:

def self.trace_execute(io=$stderr, &block)
  set_trace_func proc {|event, file, line, id, binding, classname|
    io.printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname if id.to_s == 'execute'
  }
  # trace the passed block
  yield

ensure
  # disable (note: the disable call is the last thing traced)
  set_trace_func nil
end

Затем оберните ваш вызов выполнения в блок, подобный этому:

trace_execute { execute ('SELECT 1;') }

и вставьте первые несколько строк вывода трассировки.Я подозреваю, что что-то перехватывает вызов execute до того, как адаптер db сможет его получить.

Обычно я бы рекомендовал использовать что-то вроде

puts method(:execute).inspect

, но это, вероятно, не сработает в этом случае, потому чтоmethod_missing участвует.

0 голосов
/ 15 сентября 2011

На первый взгляд, execute - это на самом деле exec-оболочка, а не db-exec.

Если честно, я обычно использую execute внутри миграций - и это, похоже, работает, то есть

  def self.up
    execute <<EOF
some SQL
EOF
  end
...