2010-08-31 13 views
15

Recientemente hemos renovado un proyecto y estamos buscando incorporar todos nuestros datos antiguos en el nuevo sistema. El problema es que el esquema es marginalmente diferente, por lo que una importación SQL directa no es posible. Debido a algunos cambios en la desnormalización y la base de datos, tendremos que hacer un poco de masaje de los datos antes de que estén listos para la importación. Me esperaba algo como esto:¿ActiveRecord habla con dos bases de datos?

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 

En el ejemplo anterior, OldUser es la lectura de la antigua base de datos, y NewUser está trabajando en la nueva base de datos. Necesito ambos conjuntos de modelos (nuevos y viejos) para conservar sus asociaciones para desnormalizar adecuadamente algunos de esos datos.

¿Hay algún proyecto/biblioteca que pueda ayudarme a hacer esto?

Respuesta

20

simplemente debe especificar sus opciones de conexión, ya sea en el modelo o en database.yml. Vayamos a la primera ruta inicialmente:

# 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 

De código regular, se utiliza el modelo como el que está acostumbrado:

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

ActiveRecord se encargará de todos los detalles para usted.

Ahora, si eres como yo, no te gusta poner ese nivel de detalles en tus modelos: nombre de usuario, contraseñas, etc. Simple: mueve esa configuración a database.yml y conéctate usando la sintaxis correcta de establish_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 

Tenga en cuenta la convención de nomenclatura - legacy_users _ # {Rails.env} es lo que estoy apuntando para aquí, y aquí está cómo hacerlo:

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 

bingo, todo lo demás funcionará bien.

+2

Tenga en cuenta que 'set_table_name' se eliminó a favor de' self.table_name'. –

2

Las opciones son:

  • Magic Models de última actualización en 2009 (a partir del 11/1/2012)

  • Connection Ninja Última actualización en 2010 (a partir del 11/1/2012)

  • DB Charmer Última actualización hace aproximadamente 6 meses (a partir del 11/1/2012)

  • Anulación establish_connection en su modelo para conectar con el db deseado

  • Activewarehouse-etl - una joya bastante activa para hacer db Extraer Transformar Cargar trabajo.

4

ACTUALIZADO con un ejemplo ampliado que muestra las llaves extranjeras en las mesas y un par de ejemplos que muestran cómo identificar los nombres de columna estándar ninguno de ruta en los carriles correctamente.

dentro de su aplicación

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

código de clase

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 

y alcance que cuando más lo necesita

Legacy::User.new 
User.new 

Legacy::User.first.companies #=> returns array of Legacy::Companies 
+0

¿Cómo funcionará esto con las asociaciones? Diga que mi Usuario tiene una Compañía. Si mi Legacy :: User tiene una asociación de empresas, ¿tendrá el valor predeterminado en el módulo Legacy o (incorrectamente) se asociará con el modelo de compañía más nuevo? –

+0

cuál es el nombre de su tabla y columna y voy a modificar el ejemplo –

Cuestiones relacionadas