如何在Rails控制台中显示运行的SQL查询?

162

当我在控制台运行查询(例如 MyModel.where(...)record.associated_things)时,我如何查看实际正在运行的数据库查询,以便更好地了解正在发生的情况?


Andrew,如果您还需要在浏览器中运行命令,可以使用 https://github.com/igorkasyanchuk/rails_db - Igor Kasyanchuk
请参考此答案:https://dev59.com/pnM_5IYBdhLWcg3whzjx#1576221 - mwfearnley
9个回答

351

Rails 3+

在控制台中输入以下代码:

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

Rails 2

在控制台输入以下代码:

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

完美,正是我所需要的。你有什么推荐去哪里找到这些小技巧的文档吗? - randombits
2
当然。http://slash7.com/2006/12/21/secrets-of-the-rails-console-ninjas/ 和 http://stackoverflow.com/questions/123494/whats-your-favourite-irb-trick ,另外http://railscasts.com/也是不错的选择。 - John Topley
2
这适用于Rails 3+,但不适用于2,请参见https://dev59.com/pnM_5IYBdhLWcg3whzjx#1576221(如果您仍在使用2):) - rogerdpack
1
而要再次禁用它: ActiveRecord::Base.logger = nil - Hula_Zell
我来这里很多次了,当我在 Chrome 中输入“Rails”时,它会将此页面显示为最佳结果。 - 23tux

49
在Rails 3+中,你可以使用ActiveRecord::Relation的to_sql方法:to_sql
User.where(:id => 3).to_sql
#=> "SELECT \"users\".* FROM \"users\"  WHERE \"users\".\"id\" = 3"

42

在Rails 4中有.explain方法。
.to_sql也可以使用,但不会显示includes)

Category.includes(:products).explain
=> EXPLAIN for: SELECT "categories".* FROM "categories" 0|0|0|SCAN TABLE categories

EXPLAIN for: SELECT "categories_products".* FROM "categories_products" WHERE "categories_products"."category_id" IN (1, 2) 0|0|0|SCAN TABLE categories_products

EXPLAIN for: SELECT "products".* FROM "products" WHERE "products"."id" IN (1, 2, 3, 4, 5, 6, 7) 0|0|0|SEARCH TABLE products USING INTEGER PRIMARY KEY (rowid=?) 0|0|0|EXECUTE LIST SUBQUERY 1

我花了很长时间才发现 .explain 可以胜任工作,而不是 .to_sql。而且 .explain 仍然不能提供可在 pg 控制台中运行的原始格式的 SQL 查询。但我需要原始查询来进行解释和分析。我想现在只能用 explain 先凑合着了。 - abhishek77in

16

我只是想让我们的生产控制台表现出与开发环境相同的行为,即将所有的SQL查询报告到控制台。

Rails.logger.level = 0

3.0.3 :001 > Rails.logger.level = 0
 => 0
3.0.3 :002 > User.last
  User Load (0.7ms)  SELECT `users`.* FROM `users` ORDER BY `users`.`id` DESC LIMIT 1
 => #<User:…>

2
相当于 Rails.logger.level = :debug - Rorrim

10

现在应该不需要再打开它了,因为默认情况下应该已经启用了:“自 Rails 5.2 开始,在开发环境日志中默认启用详细查询日志记录。” - Jarno Lamberg
1
这似乎已经被弃用了:"ActiveSupport::DeprecationException: DEPRECATION WARNING: ActiveRecord::Base.verbose_query_logs= 已经被弃用,并将在Rails 7.1中被移除。" - Sarah Vessels
这个方法确实已经被弃用了,但它已经从 AR::Base 中移除(https://github.com/rails/rails/commit/c3f43075a3c70c3b11717741426ec38a8d3cd14a),并且在 Rails 7.0 中作为 ActiveRecord.verbose_query_logs 可用。 - Dave Powers

6

最近,你可以使用这个:

https://github.com/dejan/rails_panel

它由chrome浏览器的开发者控制台面板插件和需要添加到应用程序Gemfile的gem文件组成,像这样:

group :development do
  gem 'meta_request'
end

然后再次运行:

bundle install

重新启动您的应用程序,打开它,并启动开发人员控制台,您应该看到它像这样:在此输入图片描述


4

有几个配置参数可以控制是否将SQL查询打印到日志中。

(本答案基于Rails 6.0。)

首先,请确认记录器已经配置好,并且它的@logdev具有与您期望匹配的@dev@filename

pry(main)> ActiveRecord::Base.logger

=> #<ActiveSupport::Logger:0x00007fd47b400900
 ...,
 @logdev=
  #<Logger::LogDevice:0x00007fd47b400a90
   @binmode=false,
   @dev=#<File:log/development.log>,
   @filename="log/development.log",
   ...>,
 ...>

接下来,请确保日志记录器级别设置为DEBUG

ActiveRecord::Base.logger.debug!

尝试运行查询以查看问题是否已解决:

> ActiveRecord::Base.connection.exec_query 'SELECT 1'
  SQL (0.1ms)  SELECT 1

如果查询被打印到日志文件(例如log/development.log),但没有在控制台上显示,那么您可能需要执行以下操作:

ActiveRecord::Base.logger.extend(
  ActiveSupport::Logger.broadcast(ActiveSupport::Logger.new(STDOUT))
)

如果您仍然无法获取SQL查询,那么可能是因为 ActiveRecord :: LogSubscriber 没有监听事件(例如,某些库将其停用)。请激活它:
ActiveRecord::LogSubscriber.attach_to :active_record

2

对于Rails v“6.1.7.3”,以下组合适用于我:

ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::LogSubscriber.attach_to :active_record

0

我更喜欢在config/application.rb中设置日志记录器级别:

config.after_initialize do
  Rails.logger.level = (ENV['LOG_LEVEL'] || Logger::INFO).to_i
end

在生产环境中,我的ENV['LOG_LEVEL']将被设置为Logger::INFO的值,而在我的本地机器上,它将是Logger::DEBUG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接