Rails ActiveRecord копирует данные из старой базы данных в новую базу данных - PullRequest
1 голос
/ 28 сентября 2019

Мне нужно переместить данные моего приложения из старой базы данных приложений в новую базу данных приложений.Структуры таблиц разные.Я написал следующий скрипт:

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

Код для чтения одной записи из старой базы данных

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

Далее следует код для соответствия doctor_params новой структуре таблицы.Код для создания записи в новой базе данных приведен ниже.

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

Проблема в том, что объект «Доктор» в последней строке имеет атрибуты старой базы данных.Я неправильно обрабатываю соединения с базой данных или есть другая проблема?

Я попробовал следующее

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

Но если я сделаю

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

Каким-то образом модель Доктора получитзастрял со старой базой данных.

Ответы [ 2 ]

1 голос
/ 28 сентября 2019

Я решил проблему следующим образом:

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

Это похоже на "хаккей", и я уверен, что это неэффективно при работе с большими базами данных, но это решение моей кризисной ситуации.В моей базе данных около 8000 записей, поэтому меня не беспокоит эффективность.

0 голосов
/ 28 сентября 2019

Попробуйте,

Doctor.establish_connection :new_database
Doctor.create doctor_params

с,

# 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...