2009-12-28 54 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宝石。这个棒极了。