Skip to content

Instantly share code, notes, and snippets.

@ericgj
Created September 30, 2012 02:59
Show Gist options
  • Save ericgj/3805719 to your computer and use it in GitHub Desktop.
Save ericgj/3805719 to your computer and use it in GitHub Desktop.
ER diagrams with Sequel and Graphviz
# Usage:
# ruby sequel_dot.rb [SEQUEL-DATABASE-URI] > output.dot
# Or pipe directly to Graphviz:
# ruby sequel_dot.rb [SEQUEL-DATABASE-URI] | dot -Tgif > output.gif
#
# Note adapted from Jeremy Evans' and Rohit Namjoshi's son's code at
# http://sequel.heroku.com/2010/05/29/fun-with-graphviz-and-associations/
#
# However, instead of basing graph on model associations, this uses foreign key constraints of the db tables
# Thus, this relies on the database adapter supporting #foreign_key_list.
#
require 'sequel'
require 'erb'
url = ARGV.shift
db = Sequel.connect(url)
relations = []
tables = []
label_template = <<_____
<%= table_name %> [label=<
<table border="0" cellborder="1" cellspacing="0" cellpadding="4">
<tr><td bgcolor="lightgrey" PORT="<%= table_name %>"><b><%= table_name.upcase %></b></td></tr>
<% table.columns.each do |col| %>
<tr><td PORT="<%= col.to_s %>"><%= col.to_s %></td></tr>
<% end %>
</table>
>]
_____
db.tables.each do |t|
next if t == :schema_info
tables << [t, db[t]]
fks = db.foreign_key_list(t)
fks.each do |fk|
relations << [t, fk[:table], fk[:columns], fk[:key] || [:id] ] # note assumes primary key == :id when key is nil
end
end
puts "digraph G {"
puts "node [shape=none,fontname=\"DejaVu Sans\"];"
puts "rankdir=LR"
tables.each do |table_name, table|
puts ERB.new(label_template).result(binding)
end
puts relations.map {|from_t, to_t, from_cols, to_cols|
from_cols.zip(to_cols).map do |(from_col, to_col)|
"\"#{from_t}\":\"#{from_col.to_s}\"" +
" -> " +
"\"#{to_t}\":\"#{to_col.to_s}\"" +
";"
end
}.sort
puts "}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment