ActiveRecord общаться с двумя базами данных? - PullRequest
15 голосов
/ 31 августа 2010

Мы недавно обновили проект и надеемся перенести все наши старые данные в новую систему.Проблема в том, что схема немного отличается, поэтому прямой импорт SQL невозможен.Из-за некоторой денормализации и изменений в базе данных нам нужно будет выполнить некоторую массивацию данных, прежде чем они будут готовы к импорту.Я надеялся на что-то вроде этого:

OldUser.all.each do |ou|
  NewUser.create({
    :first_name   => ou.first_name
    :last_name    => ou.last_name
    :login        => ou.login
    :company_name => ou.company.name
  })
end

В приведенном выше примере OldUser читает из старой базы данных, а NewUser работает с новой базой данных.Мне нужны оба набора моделей (новые и старые), чтобы сохранить их ассоциации, чтобы должным образом денормализовать некоторые из этих данных.

Есть ли какой-нибудь проект / библиотека, который может помочь мне сделать это?

Ответы [ 3 ]

20 голосов
/ 01 сентября 2010

Вы должны просто указать параметры подключения в модели или в database.yml.Давайте сначала пойдем по 1-му маршруту:

# This is the new users table - connects to development/test/production
# DB from database.yml
class User < ActiveRecord::Base
end

class OldUser < ActiveRecord::Base
  establish_connection :adapter  => "postgresql",
                       :database => "legacy_users",
                       :username => "whatever",
                       :password => "something"
  set_table_name "u_users" # Whatever you require
  belongs_to :company, :class_name => "OldCompany", :foreign_key => "fk_company_id"
end

class OldCompany < ActiveRecord::Base
  establish_connection :adapter  => "postgresql",
                       :database => "legacy_users",
                       :username => "whatever",
                       :password => "something"
  set_table_name "u_company" # Whatever you require
  has_many :users, :class_name => "OldUser", :foreign_key => "fk_company_id"
end

Из обычного кода вы будете использовать модели, к которым привыкли:

OldUser.find_each do |ouser|
  User.create!(:username => ouser.username, :company_name => ouser.company.name)
end

ActiveRecord обработает все детали за вас.

Теперь, если вы похожи на меня, вам не нравится помещать такой уровень детализации в ваших моделях - имя пользователя, пароли и т. Д. Просто - переместите эту конфигурацию в database.yml и подключитесь, используя правильный синтаксис Estab_connection:

# database.yml
development:
  adapter: postgresql
  # go on as usual, for all 3 envs

legacy_users_development:
  adapter:  postgresql
  database: legacy_users
  username: whatever
  password: something

Обратите внимание на соглашение об именах - legacy_users _ # {Rails.env} - вот к чему я стремлюсь, и вот как это сделать:

class OldUser < ActiveRecord::Base
  establish_connection "legacy_users_#{Rails.env}"
  set_table_name "u_users" # Whatever you require
  belongs_to :company, :class_name => "OldCompany", :foreign_key => "fk_company_id"
end

Бинго, всеостальное будет работать просто отлично.

5 голосов
/ 31 августа 2010

ОБНОВЛЕНО с расширенным примером, показывающим внешние ключи в таблицах, и парой примеров, показывающих, как правильно определить ни одно стандартное имя столбца для правильной маршрутизации в рельсах.

внутри вашего приложения

models
  |_ legacy
     |_ base.rb
     |_ user.rb
     |_ company.rb
  |_ user.rb

код класса

module Legacy
  class Base < ActiveRecord::Base
    self.abstract_class :true
    establish_connection "database here"
  end
end

module Legacy
  class User < Legacy::Base
    :has_many :companies, :class_name => 'Legacy::Company', :foreign_key => 'user_id'
  end
end

module Legacy
  class Company < Legacy::Base
    set_table_name 'companies'
    set_primary_key 'someId'
    belongs_to :user, :class_name => 'Legacy::User', :foreign_key => 'operator'
  end
end

и охватите его там, где вам нужно

Legacy::User.new
User.new

Legacy::User.first.companies #=> returns array of Legacy::Companies
2 голосов
/ 31 августа 2010

Доступны следующие варианты:

  • Магические модели Последнее обновление в 2009 г. (по состоянию на 11 ноября 2012 г.)

  • Соединение ниндзя Последнее обновление в 2010 году (по состоянию на 01.11.2012)

  • DB Charmer Последнее обновление около 6 месяцев назад (по состоянию на 01.11.2012)

  • Переопределение establish_connection в вашей модели для подключения к нужному дБ

  • Activewarehouse-etl - aдовольно активный гем для выполнения db Извлечение работы Transform Load.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...