postgreSQL模式的Rails迁移

postgreSQL模式的Rails迁移,sql,ruby-on-rails,postgresql,migration,multi-tenant,Sql,Ruby On Rails,Postgresql,Migration,Multi Tenant,我正在为不同的客户端开发一个使用PostgreSQL模式的多租户rails应用程序。Rails迁移不能在开箱即用的情况下使用多个模式,因此我做了以下rake任务来迁移所有模式,并且似乎可以工作。我的问题是,其他人是否实施了更好、更优雅的解决方案。如果有一个好的教程,包括使用多种模式的PostgreSQL的rails代码示例,我也会非常高兴。到目前为止,我只找到了关于这个主题的一个很好的演示,以及我的目标tomayko.com/writings/rails-multiple-connections

我正在为不同的客户端开发一个使用PostgreSQL模式的多租户rails应用程序。Rails迁移不能在开箱即用的情况下使用多个模式,因此我做了以下rake任务来迁移所有模式,并且似乎可以工作。我的问题是,其他人是否实施了更好、更优雅的解决方案。如果有一个好的教程,包括使用多种模式的PostgreSQL的rails代码示例,我也会非常高兴。到目前为止,我只找到了关于这个主题的一个很好的演示,以及我的目标tomayko.com/writings/rails-multiple-connections的一个例子

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

我不确定我的问题是否正确,但您是否只需要在
数据库中声明几个环境。yml
每个环境中都指定了不同的“数据库”?

我有一个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
然后我像往常一样使用迁移,这样我可以继续调用rake:migrate 现在,在迁移中,您可以使用:

...
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
我之所以这样写是因为这些场景,即多个应用程序共享同一个数据库的情况。可能有一种Rails方法来处理这个问题(引擎?),但我经常有另一个应用程序不是Rails,它也需要数据库。。。然后呢

在这种情况下,pg_migrate的关键特性是它可以生成一个ruby gem;因此,可以将数据库模式与所有下游应用程序分开维护,但所有应用程序都可以引用它

在Rails gem文件中,使用pg_migrate的“package”命令构建ruby gem后,可以执行以下操作:

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

检查为这个目的而建造的宝石。这真是太棒了。

就我所知,Liquibase确实可以使用模式know@JanningLiquibase不是一个与rails使用的ActiveRecord模式一起工作的解决方案。postgres中的模式在数据库中。也就是说,一个数据库可以有多个模式。