2009-12-28 80 views
15

我正在爲不同客戶端使用PostgreSQL模式的多租戶Rails應用程序。 Rails遷移不能用於開箱即用的多個模式,所以我做了下面的rake任務來遷移所有模式,它似乎工作。我的問題是如果其他人已經實施了更好更優雅的解決方案。我也會很高興看到一個很好的教程,其中包括使用多個模式的PostgreSQL的rails代碼示例。到目前爲止,我只找到關於這一主題http://aac2009.confreaks.com/06-feb-2009-14-30-writing-multi-tenant-applications-in-rails-guy-naor.html好介紹,什麼我的目標tomayko.com/writings/rails-multiple-connections的例子針對postgreSQL模式的Rails遷移

desc 'Migrates all postgres schemas' 
task :schemas do 
    # get all schemas 
    env = "#{RAILS_ENV}" 
    config = YAML::load(File.open('config/database.yml')) 
    ActiveRecord::Base.establish_connection(config[env]) 
    schemas = ActiveRecord::Base.connection.select_values("select * from pg_namespace where nspname != 'information_schema' AND nspname NOT LIKE 'pg%'") 
    puts "Migrate schemas: #{schemas.inspect}" 
    # migrate each schema 
    schemas.each do |schema| 
    puts "Migrate schema: #{schema}" 
    config = YAML::load(File.open('config/database.yml')) 
    config[env]["schema_search_path"] = schema 
    ActiveRecord::Base.establish_connection(config[env]) 
    ActiveRecord::Base.logger = Logger.new(STDOUT) 
    ActiveRecord::Migrator.migrate('db/migrate', ENV["VERSION"] ? ENV["VERSION"].to_i : nil) 
    end 
end 
+0

Liquibase根據模式工作,盡我所知 – Janning 2010-05-29 16:10:22

+1

@Janning Liquibase不是一個可以與Rails使用的ActiveRecord模塊一起工作的解決方案。 – lillq 2011-11-27 19:46:42

回答

0

我不知道如果我得到了問題是正確的,但是您是否需要在您的database.yml中聲明幾個具有不同「數據庫」的環境?

+2

postgres中的模式位於數據庫中。 I.E一個數據庫可以有很多模式。 – lillq 2011-11-27 19:21:25

8

我有我使用並具有處理遷移以下方法schema_utils庫:

def self.with_schema(schema_name, &block) 
    conn = ActiveRecord::Base.connection 
    old_schema_search_path = conn.schema_search_path 
    conn.schema_search_path = schema_name 
    begin 
     yield 
    ensure 
     conn.schema_search_path = old_schema_search_path 
    end 
    end 

然後我用遷移正常,所以我可以繼續撥打耙:遷移 現在,在你遷移你可以使用:

... 
schemas.each do |schema| 
    SchemaUtils.with_schema(schema) do 
    #Put migration code here 
    #e.g. add_column :xyz, ... 
    end 
end 

因爲我往往會被映射模式來解釋我的代碼執行以下操作:

Account.for_each do |account| 
    SchemaUtils.with_schema(account.code) do 
    #Put migration code here 
    end 
end 
0

由於這些情況,即多個應用程序共享相同數據庫的情況,我寫了pg_migrate。有可能是一個Rails的方式來處理這個(引擎?),但我經常有另一個應用程序不是Rails需要數據庫太...然後呢?

在這種情況下,pg_migrate的關鍵特性是它可以生成一個紅寶石;因此可以將數據庫模式與所有下游應用程序分開維護,但都可以引用它。

在你的Rails的Gemfile,你已經建立了使用pg_migrate的「一攬子」命令紅寶石寶石後,你可以這樣做:

gem 'my_db', gem 'jam_db', :path=> "../my_db/gem_package" 
0

檢查已內置只是爲這一目的apartment寶石。這個棒極了。