Skip to content

Instantly share code, notes, and snippets.

@jonathangaldino
Forked from GlenCrawford/schema_dumper.rb
Created May 3, 2023 17:55
Show Gist options
  • Save jonathangaldino/f60fab57b60ea16c87d71e5926b01676 to your computer and use it in GitHub Desktop.
Save jonathangaldino/f60fab57b60ea16c87d71e5926b01676 to your computer and use it in GitHub Desktop.
Patching Rails database schema dumps to support multiple PostgreSQL schemas.
# Overrides Rails file activerecord/lib/active_record/schema_dumper.rb to
# include all schema information in the db/schema.rb file, for example, in the
# create_table statements. This allows for a working development database
# to be built from a schema.rb file generated by rake db:schema:dump.
#
# This is essentially a rebuild of the "schema_plus_multischema" gem (which is
# unfortunately only compatible with Rails ~> 4.2).
#
# Tested with Rails 6.0.
module ActiveRecord
class SchemaDumper
# Overridden in order to call new method "schemas".
def dump(stream)
header(stream)
extensions(stream)
schemas(stream)
tables(stream)
trailer(stream)
clean(stream)
stream
end
private
# Adds following lines just after the extensions:
# * connection.execute "CREATE SCHEMA ..."
# * connection.schema_search_path = ...
def schemas(stream)
@connection.schema_search_path.split(',').each do |name|
stream.puts %Q{ connection.execute "CREATE SCHEMA IF NOT EXISTS #{name}"}
end
stream.puts ""
stream.puts %Q{ connection.schema_search_path = #{@connection.schema_search_path.inspect}}
stream.puts ""
end
# Overridden in order to build a list of tables with their schema prefix
# (rest of the method is the same).
def tables(stream)
table_query = <<-SQL
SELECT schemaname, tablename
FROM pg_tables
WHERE schemaname = ANY(current_schemas(false))
SQL
sorted_tables = @connection.exec_query(table_query, 'SCHEMA').map do |table|
"#{table['schemaname']}.#{table['tablename']}"
end.sort
sorted_tables.each do |table_name|
table(table_name, stream) unless ignored?(table_name)
end
if @connection.supports_foreign_keys?
sorted_tables.each do |tbl|
foreign_keys(tbl, stream) unless ignored?(tbl)
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment