Programming

Ruby on Rails에서 지정된 ActiveRecord 쿼리에 의해 생성되는 SQL을 어떻게 볼 수 있습니까?

procodes 2020. 7. 29. 22:24
반응형

Ruby on Rails에서 지정된 ActiveRecord 쿼리에 의해 생성되는 SQL을 어떻게 볼 수 있습니까?


주어진 ActiveRecord 쿼리가 생성 할 SQL 문을보고 싶습니다. 쿼리가 발행 된 후 로그 에서이 정보를 얻을 수 있다는 것을 알고 있지만 ActiveRecord 쿼리에서 호출 할 수있는 메소드가 있는지 궁금합니다.

예를 들면 다음과 같습니다.

SampleModel.find(:all, :select => "DISTINCT(*)", :conditions => ["`date` > #{self.date}"], :limit => 1, :order => '`date`', :group => "`date`")

irb 콘솔을 열고이 쿼리가 생성 할 SQL을 보여 주지만 반드시 쿼리를 실행할 필요는없는 메소드를 선택하고 싶습니다.


마지막 으로이 작업을 시도했을 때 공식적인 방법은 없었습니다. 나는 find그들의 친구가 직접 쿼리를 생성하는 데 사용하는 기능을 사용했습니다. 그것은 개인 API이므로 Rails 3이 그것을 완전히 깨뜨릴 위험이 있지만 디버깅을 위해서는 괜찮은 솔루션입니다.

이 방법은 비공개이므로 construct_finder_sql(options)( lib/active_record/base.rb:1681) 사용해야 send합니다.

편집 : construct_finder_sql Rails 5.1.0.beta1에서 제거되었습니다 .


penger와 비슷하지만 클래스가로드되고 로거가 캐시 된 후에도 콘솔에서 언제든지 작동합니다.

레일 2의 경우 :

ActiveRecord::Base.connection.instance_variable_set :@logger, Logger.new(STDOUT)

Rails 3.0.x의 경우 :

ActiveRecord::Base.logger = Logger.new(STDOUT)

Rails> = 3.1.0의 경우 콘솔에서 기본적으로 이미 수행되었습니다. 너무 시끄럽고 끄기원할 경우 다음을 수행 할 수 있습니다.

ActiveRecord::Base.logger = nil

막대기 puts query_object.class와 작업은 다음 문서를 조회 개체의 유형을 볼 수 어딘가에.

예를 들어, Rails 3.0에서는 메소드 ActiveRecord::Relation가있는 범위를 사용 #to_sql합니다. 예를 들면 다음과 같습니다.

class Contact < ActiveRecord::Base
  scope :frequently_contacted, where('messages_count > 10000')
end

그런 다음 어딘가에 할 수 있습니다 :

puts Contact.frequently_contacted.to_sql

이것은 오래된 질문 일 수도 있지만 다음을 사용합니다.

SampleModel.find(:all,
                 :select => "DISTINCT(*)",
                 :conditions => ["`date` > #{self.date}"], 
                 :limit=> 1, 
                 :order => '`date`',
                 :group => "`date`"
                 ).explain

explain방법은 수행 할 작업에 대한 자세한 SQL 문을 제공합니다.


to_sql메소드를 사용 하면 실행할 SQL 쿼리가 출력됩니다. 활성 레코드 관계에서 작동합니다.

irb(main):033:0> User.limit(10).where(:username => 'banana').to_sql
=> "SELECT  "users".* FROM "users"  WHERE "users"."username" = 'banana'
LIMIT 10"

를 수행 find하면 작동하지 않으므로 해당 ID를 쿼리에 수동으로 추가하거나 where를 사용하여 실행해야합니다.

irb(main):037:0* User.where(id: 1).to_sql
=> "SELECT "users".* FROM "users"  WHERE "users"."id" = 1"

이것은 콘솔에서 SQL을 생성하기 위해 일반적으로하는 일입니다.

-> script/console
Loading development environment (Rails 2.1.2)
>> ActiveRecord::Base.logger = Logger.new STDOUT
>> Event.first

콘솔을 처음 시작할 때이 작업을 수행해야합니다. 코드를 입력 한 후에이 작업을 수행하면 작동하지 않는 것 같습니다

정말 이것에 대한 신용을 취할 수 없습니다, 오래 전에 누군가의 블로그에서 발견하고 누구의 블로그인지 기억할 수 없습니다.


홈 디렉토리에 .irbrc 파일을 작성하고 다음에 붙여 넣으십시오.

if ENV.include?('RAILS_ENV') && !Object.const_defined?('RAILS_DEFAULT_LOGGER')
  require 'logger'
  RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
end

그러면 SQL 문이 irb 세션으로 출력됩니다.

EDIT: Sorry that will execute the query still, but it's closest I know of.

EDIT: Now with arel, you can build up scopes/methods as long as the object returns ActiveRecord::Relation and call .to_sql on it and it will out put the sql that is going to be executed.


My typical way to see what sql it uses is to introduce a "bug" in the sql, then you'll get an error messages spit out to the normal logger (and web screen) that has the sql in question. No need to find where stdout is going...


Try the show_sql plugin. The plugin enables you to print the SQL without running it

SampleModel.sql(:select => "DISTINCT(*)", :conditions => ["`date` > #{self.date}"], :limit => 1, :order => '`date`', :group => "`date`")

You could change the connection's log method to raise an exception, preventing the query from being run.

It's a total hack, but it seems to work for me (Rails 2.2.2, MySQL):

module ActiveRecord
  module ConnectionAdapters
    class AbstractAdapter
      def log_with_raise(sql, name, &block)
        puts sql
        raise 'aborting select' if caller.any? { |l| l =~ /`select'/ }
        log_without_raise(sql, name, &block)
      end
      alias_method_chain :log, :raise
    end
  end
end

In Rails 3 you can add this line to the config/environments/development.rb

config.active_record.logger = Logger.new(STDOUT)

It will however execute the query. But half got answered :

참고URL : https://stackoverflow.com/questions/1344232/how-can-i-see-the-sql-that-will-be-generated-by-a-given-activerecord-query-in-ru

반응형