postgreSQL 模式的 Rails 迁移
我正在为不同的客户端使用 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
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
I'm working on a multi-tenant rails application using PostgreSQL schemas for different clients. Rails migrations don't work with multiple schemas out of the box, so I made the following rake task to migrate all schemas and it seems to work. My question is if others have implemented better and more elegant solutions. I would also be really happy with a good tutorial including rails code examples for PostgreSQL using multiple schemas. So far I have only found a good presentation on the subject http://aac2009.confreaks.com/06-feb-2009-14-30-writing-multi-tenant-applications-in-rails-guy-naor.html and an example of what I'm aiming for 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我有一个 schema_utils 库,我使用它并具有以下处理迁移的方法:
然后我照常使用迁移,这样我就可以继续调用 rake:migrate
现在,在迁移中您可以使用:
因为我倾向于将架构映射到帐户代码,所以我执行以下操作:
I have a schema_utils library which I use and has the following method for handling migrations:
I then use migrations as normal so I can continue to call rake:migrate
Now, in your migrations you can use:
Because I tend to be mapping schemas to account codes I do the following:
检查专门为此目的构建的
apartment
gem。太棒了。Check the
apartment
gem that's been built just for that purpose. It's brilliant.我不确定我的问题是否正确,但是您不需要在
database.yml
中声明更多环境,并在每个环境中指定不同的“数据库”吗?I'm not sure if I got the question right but don't you just need to declare a few more environments in your
database.yml
with different "database" specified in each?我写 pg_migrate 是因为这些场景,即多个应用程序共享同一个数据库的情况。可能有一种 Rails 方法来处理这个问题(引擎?),但我经常有另一个不是 Rails 的应用程序也需要数据库......然后呢?
在这种情况下,pg_migrate 的关键特性是它可以生成 ruby gem;因此可以将数据库模式与所有下游应用程序分开维护,但所有下游应用程序都可以引用它。
在 Rails Gemfile 中,使用 pg_migrate 的“package”命令构建 ruby gem 后,您可以执行以下操作:
I wrote pg_migrate because of these scenarios, i.e., situations in which multiple applications share the same database. There is probably a Rails way to handle this (engines?) but I too often have another app that's not Rails that needs the database too... then what?
In this case, the key feature of pg_migrate is it can generate a ruby gem; so it becomes possible to maintain your database schema separately from all the downstream applications, but all can reference it.
In your Rails Gemfile, after you've built the ruby gem using pg_migrate's 'package' command, you can do: