Недавно мы обновили проект и надеемся перенести все наши старые данные в новую систему. Проблема в том, что схема незначительно отличается, поэтому прямой импорт 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 работает над новой базой данных. Мне нужны оба набора моделей (новые и старые) для сохранения их ассоциаций, чтобы должным образом денормализовать некоторые из этих данных.
Есть ли какой-нибудь проект / библиотека, который может помочь мне сделать это?
Вы должны просто указать параметры подключения либо в модели, либо в файле database.yml. Сначала пойдем по первому пути:
# 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 и подключитесь, используя правильный синтаксис install_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
Бинго, все остальное будет работать нормально.
ОБНОВЛЕНО с расширенным примером, показывающим внешние ключи в таблицах, и парой примеров, показывающих, как определить нестандартные имена столбцов для правильной маршрутизации в рельсах.
внутри вашего приложения
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
Ваш Варианты:
Magic Models Последнее обновление в 2009 г. (по состоянию на 01.11.2012)
Connection Ninja Последнее обновление в 2010 г. (по состоянию на 01.11.2012)
DB Charmer Последнее обновление примерно 6 месяцев назад (по состоянию на 01.11.2012)
Переопределение install_connection
в вашей модели для подключения к нужной базе данных
Activewarehouse-etl — довольно активный гем для сделать db Извлечь Преобразование Загрузить работу.