开发者

Why is `execute` dropping back to the shell instead of sending SQL directly to my Postgres server?

I have a migration which is using execute to send raw SQL to the Postgres backend.

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

  def self.down
  end
end

Instead of going to my database, it seems execute is going to the shell:

** 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

But, when I instead do

ActiveRecord::Base.connection.execute(sql)
开发者_JAVA百科

It works as expected.

Why is this?

I'm using Rails 3.0.9 and the pg gem.


Add this to your migration:

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

Then wrap your execute call in a block like this:

trace_execute { execute ('SELECT 1;') }

and paste the first few lines of trace output. I suspect something is intercepting the execute call before the db adapter can receive it.

Usually I'd recommend using something like

puts method(:execute).inspect

but that probably won't work in this case because method_missing is involved.


First glance is that execute is actually a shell exec - not a db exec.

I will be honest, I normally do use execute inside migrations - and that seems to work, i.e.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜