Pretty Print SQL in Ruby Pretty Print SQL in Ruby ruby ruby

Pretty Print SQL in Ruby


Try this:

git clone https://github.com/sonota/anbt-sql-formattercd anbt-sql-formatterrails setup.rb

Then, in a Rails initializer:

# config/initializers/pretty_format_sql.rbclass String  def pretty_format_sql    require "anbt-sql-formatter/formatter"    rule = AnbtSql::Rule.new    rule.keyword = AnbtSql::Rule::KEYWORD_UPPER_CASE    %w(count sum substr date).each{|func_name|      rule.function_names << func_name.upcase    }    rule.indent_string = "    "    formatter = AnbtSql::Formatter.new(rule)    formatter.format(self)  endend

Test:

rails console# Some complex SQLputs Recipe.joins(:festivity).where(['? BETWEEN festivities.starts_at AND festivities.ends_at', Time.utc(0,Time.now.month,Time.now.day,12,0,0)]).to_sql.pretty_format_sqlSELECT        "recipes" . *    FROM        "recipes" INNER JOIN "festivities"            ON "festivities" . "id" = "recipes" . "festivity_id"    WHERE        (            '0000-04-27 12:00:00.000000' BETWEEN festivities.starts_at AND festivities.ends_at        ) => nil 

I leave refining to you (refactoring: monkey-patching -> module, customized formatting, etc :-) )


The anbt-sql-formatter of the first answer is available as a gem, you can install it with:

gem install anbt-sql-formatter

Here an example of the usage:

require "anbt-sql-formatter/formatter"rule = AnbtSql::Rule.new  formatter = AnbtSql::Formatter.new(rule)["SELECT `col1`, `col2` FROM `table` WHERE ((`col1` = 1) AND (`col2` = 5))","SELECT `col1`, `col2` FROM `table` WHERE (`col1` = 1) AND (`col2` = 5)","SELECT `col1` FROM `table` WHERE (`col1` IN (SELECT * FROM `table21` WHERE (`col2` = 5)))","SELECT `col1` FROM `table` INNER JOIN `tab2` ON (`tab1`.`id` = `tab2`.`id1`) WHERE ((`id` >= 1) AND (`id` <= 5))",].each{|sql_cmd|   puts "======"  puts sql_cmd  puts formatter.format(sql_cmd)}

The result:

======SELECT `col1`, `col2` FROM `table` WHERE ((`col1` = 1) AND (`col2` = 5))SELECT        `col1`        ,`col2`    FROM        `table`    WHERE        (            (                `col1` = 1            )            AND (                `col2` = 5            )        )======SELECT `col1`, `col2` FROM `table` WHERE (`col1` = 1) AND (`col2` = 5)SELECT        `col1`        ,`col2`    FROM        `table`    WHERE        (            `col1` = 1        )        AND (            `col2` = 5        )======SELECT `col1` FROM `table` WHERE (`col1` IN (SELECT * FROM `table21` WHERE (`col2` = 5)))SELECT        `col1`    FROM        `table`    WHERE        (            `col1` IN (                SELECT                        *                    FROM                        `table21`                    WHERE                        (                            `col2` = 5                        )            )        )======SELECT `col1` FROM `table` INNER JOIN `tab2` ON (`tab1`.`id` = `tab2`.`id1`) WHERE ((`id` >= 1) AND (`id` <= 5))SELECT        `col1`    FROM        `table` INNER JOIN `tab2`            ON (            `tab1`.`id` = `tab2`.`id1`        )    WHERE        (            (                `id` >= 1            )            AND (                `id` <= 5            )        )

There is also the possibility to extend the rules, e.g.

# User defined additional functions:%w(count sum substr date coalesce).each{|func_name|  rule.function_names << func_name.upcase}


Six years later, here's another option: https://github.com/kvokka/pp_sql

"Replace standard ActiveRecord#to_sql method with anbt-sql-formatter gem for pretty SQL code output in console. Rails log will be formatted also."

Uses anbt-sql-formatter under the hood, but makes this the default behavior for .to_sql