Vikram Sharma
Vikram Sharma

Reputation: 526

Rails ActiveRecord Copy Data from Old Database to New Database

I have to move my app data from the old app database to new app database. The table structures are different. I have written the following script.

require 'mysql2'
require 'active_record'

old_database = {
adapter:  "mysql2",
host:     "localhost",
username: "foo",
password: "bar",
database: "old_db",
socket: "/var/run/mysqld/mysqld.sock"
}

new_database = {
adapter:  "mysql2",
encoding: "utf8mb4",
collation: "utf8mb4_bin",
host:     "localhost",
username: "foo",
password: "bar",
database: "new_db",
socket: "/var/run/mysqld/mysqld.sock"
}

class Doctor < ActiveRecord::Base  
end

Code for reading a single record from old database

ActiveRecord::Base.establish_connection(old_database)
  doctor_attributes = Doctor.order(:id).limit(1).offset(offset).first.attributes
  ActiveRecord::Base.remove_connection

This is followed by code for conforming doctor_params with new table structure. The code for creating an entry in new database is as under.

ActiveRecord::Base.establish_connection(new_database)
Doctor.create(doctor_params)

The issue is the Doctor object in the last line has attributes of the old database. Am I not handling database connections properly or is there another issue?

I tried the following

ActiveRecord::Base.establish_connection(old_db)
ActiveRecord::Base.establish_connection(new_db)
doctor = Doctor.new #Instance of doctor as per new database

But if I do

ActiveRecord::Base.establish_connection(old_db)
doctor = Doctor.new # instance of doctor as per old database
ActiveRecord::Base.establish_connection(new_db)
doctor = Doctor.new # Still instance of doctor as per new database

Somehow the Doctor model gets stuck with old database.

Upvotes: 1

Views: 559

Answers (2)

Vikram Sharma
Vikram Sharma

Reputation: 526

I solved the problem as under

require 'mysql2'
require 'active_record'    

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
end

class Doctor < ApplicationRecord
  old_database = {
    adapter:  "mysql2",
    host:     "localhost",
    username: "foo",
    password: "bar",
    database: "old_db"
  }
  establish_connection(old_database)
end

class NewDoctor < ApplicationRecord
  new_database = {
    adapter:  "mysql2",
    encoding: "utf8mb4",
    collation: "utf8mb4_bin",
    host:     "localhost",
    username: "foo",
    password: "bar",
    database: "new_db",
    socket: "/var/run/mysqld/mysqld.sock"
  }
  self.table_name = 'doctors'
  establish_connection(new_database)
end

It feels "hackey" and I am sure it is not efficient when dealing with large databases but it is a solution to my crisis situation. My database has around 8000 entries so I am not worried by efficiency consideration.

Upvotes: 1

Sujan Adiga
Sujan Adiga

Reputation: 1371

Try,

Doctor.establish_connection :new_database
Doctor.create doctor_params

with,

# config/database.yml

default: &default
  adapter: mysql2
  host: localhost
  username: foo
  password: bar
  socket: /var/run/mysqld/mysqld.sock

old_database:
  <<: *default
  database: old_db

new_database:
  <<: *default
  database: new_db
  encoding: utf8mb4
  collation: utf8mb4_bin

Upvotes: 0

Related Questions