Skip to content

Instantly share code, notes, and snippets.

@mdchaney
Created October 1, 2018 13:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mdchaney/0ae5622b2351cd5ff87d5e436e649e2d to your computer and use it in GitHub Desktop.
Save mdchaney/0ae5622b2351cd5ff87d5e436e649e2d to your computer and use it in GitHub Desktop.
Recursively remove data from tables in PGSQL, considering foreign keys
#!/usr/bin/env ruby
@verbose = true
tables_to_clear = ARGV.dup.freeze
# Alternately, clear out everything but these tables
#UNCLEARED_TABLES=%w{ ar_internal_metadata schema_migrations }
#tables_to_clear = (ActiveRecord::Base.connection.tables.sort - UNCLEARED_TABLES).freeze
# reset a sequence to 0
def reset_sequence(table, id='id', sequence=false)
sequence="#{table}_#{id}_seq" unless sequence
ActiveRecord::Base.connection.execute %{select setval('#{sequence}', 1, false)}
end
@dependencies = tables_to_clear.each_with_object({}) do |table_name,o|
ActiveRecord::Base.connection.foreign_keys(table_name).each do |fk|
if !UNCLEARED_TABLES.include?(fk.to_table) && !UNCLEARED_TABLES.include?(fk.from_table) && fk.from_table != fk.to_table
o[fk.to_table] ||= []
o[fk.to_table].push fk.from_table
end
end
end
puts "Clearing old data" if @verbose
# Before I clear "table", I have to clear all tables in dependencies["table"].
# Pray there are no circular dependencies :)
@already_cleared = {}
def recursively_delete_all(table_name)
if @dependencies[table_name] && @dependencies[table_name].any?
@dependencies[table_name].each do |dependent_table_name|
recursively_delete_all(dependent_table_name)
end
end
unless @already_cleared[table_name]
puts " " + table_name if @verbose
ActiveRecord::Base.connection.exec_delete("delete from #{table_name}")
if ActiveRecord::Base.connection.columns(table_name).any? { |c| c.name == 'id' }
reset_sequence table_name
end
@already_cleared[table_name] = true
end
end
ActiveRecord::Base.connection.transaction do
tables_to_clear.each do |table_name|
recursively_delete_all(table_name)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment