[Rails] Full database export/import

Gleb Arshinov gleb at barsook.com
Tue Nov 2 00:35:03 GMT 2004


I wanted to be able to backup the whole application in plain-text
database-indepent format.  This turned out to be surprisingly easy
with YAML, though I did have to implement some hacks.  I am including
pruned implementation below as FYI and to get some feedback.  In
particular, having a more general solution for YAMLizing/unYAMLizing
many-to-many relationships in Active Record itself would be nice.

For reference entity relationships are:
      customers (one-to-many) sites
      sites (many-to-many) circuits

Gleb

  def export_all
    all_objects = {}
    all_objects['customers'] = Customer.find_all
    all_objects['sites'] = Site.find_all
    all_objects['circuits'] = Circuit.find_all.each { |circuit|
      # hack to transport many-to-many data
      circuit.sites             # populates @sites member
    }

    result = all_objects.to_yaml
    result.gsub!(/\n/, "\r\n")   # TODO: general functionality for line endings
    send_string_as_file(result, :filename => "app_backup.txt",
                                :type => 'text/plain')
  end

  def import_all
    text_to_import = @params["import"]["text"]
    all_objects = YAML.load(text_to_import)

    @customers = all_objects['customers']
    @customers.each { |customer|
      customer.instance_variable_set "@new_record", true
      customer.save
    }

    @sites = all_objects['sites']
    @sites.each { |site|
      site.instance_variable_set "@new_record", true
      site.save
    }

    @circuits = all_objects['circuits']
    @circuits.each { |circuit|
      circuit.instance_variable_set "@new_record", true
      sites = circuit.sites     # save for the future
      circuit.save

      # now update with child sites
      circuit = Circuit.find(circuit.id)
      circuit.add_sites(sites)
      circuit.save
    }
  end

  def destroy_all
    Customer.destroy_all
    Circuit.destroy_all
    Site.destroy_all

    redirect_to :action => "index"
  end

Sample of the file:

--- 
devices: 
  - !ruby/object:Device 
    attributes: 
      name: MRI-123-4
      site_id: "1"
      platform: ''
      id: "2"
      description: ''
      ipx_internal_network: ''
      ip_address: 10.1.1.2
      ipx_network_name: ''
  - !ruby/object:Device 
    attributes: 
      name: ''
      site_id: "1"
      platform: Netware 5.1
      id: "3"
      description: phone system
      ipx_internal_network: ''
      ip_address: 10.1.1.3
      ipx_network_name: "68"
circuits: 
  - !ruby/object:Circuit 
    attributes: 
      name: Global Inc. Buffalo Grove POS to Toolshed FT1
      router_port: ''
      router: ''
      id: 8
      line_type: FT1
    sites: 
      - !ruby/object:Site 
        attributes: 
          name: Buffalo Grove Toolshed
          subnet_id: "0"
          id: "7"
          customer_id: "2"
      - !ruby/object:Site 
        attributes: 
          name: Buffalo Grove POS
          subnet_id: "0"
          id: "8"
          customer_id: "2"
sites: 
  - !ruby/object:Site 
    attributes: 
      name: Mundelein HQ
      subnet_id: "0"
      id: "11"
      customer_id: "5"
  - !ruby/object:Site 
    attributes: 
      name: Niles
      subnet_id: "0"
      id: "10"
      customer_id: "2"


More information about the Rails mailing list