使用多个PostgreSQL模式与Rails模型

79

我有一个用于Rails应用程序的PostgreSQL数据库。在名为“public”的模式中存储主要的Rails模型表等。我创建了一个名为“discogs”的模式,其中将具有与“public”模式中有时相同的名称的表,这也是我使用模式组织它的原因之一。

如何在我的应用程序中设置来自“discogs”模式的模型?我将使用Sunspot让Solr也索引这些模型。我不确定应该如何做。


2
在通过db:create rake任务设置数据库时,如何创建非“public”模式?将模式添加到template1数据库是一种可能性。但是否有一种方法可以作为正常的rails/rake开发过程的一部分来完成它? - TsenYing
@TsenYing,有一个名为pg_power gem的选项,可以使用它来实现这个功能。它的主页在此:https://github.com/TMXCredit/pg_power。不过,它已经有2年没有更新了。另一个选项是在“db”命名空间中编写*create* rake任务,并将您的内容添加到其中。 - mlt
7个回答

122

在database.yml中设置PostgreSQL适配器的schema_search_path会解决你的问题吗?

development:
  adapter: postgresql
  encoding: utf-8
  database: solidus
  host: 127.0.0.1
  port: 5432
  username: postgres
  password: postgres
  schema_search_path: "discogs,public"

或者,您可以为每个模式指定不同的连接:

public_schema:
  adapter: postgresql
  encoding: utf-8
  database: solidus
  host: 127.0.0.1
  port: 5432
  username: postgres
  password: postgres
  schema_search_path: "public"

discogs_schema:
  adapter: postgresql
  encoding: utf-8
  database: solidus
  host: 127.0.0.1
  port: 5432
  username: postgres
  password: postgres
  schema_search_path: "discogs"
在每个定义连接之后,创建两个模型:
class PublicSchema < ActiveRecord::Base
  self.abstract_class = true
  establish_connection :public_schema
end

class DiscoGsSchema < ActiveRecord::Base
  self.abstract_class = true
  establish_connection :discogs_schema
end

而且,你所有的模型都继承自相应的模式:

class MyModelFromPublic < PublicSchema
  set_table_name :my_table_name
end

class MyOtherModelFromDiscoGs < DiscoGsSchema
  set_table_name :disco
end

11
看起来你应该将 self.abstract_class = true 添加到 *Schema 类中,以避免不存在表格的问题。 - Ivan Velichko
1
schema_search_path: 配置非常重要,如果您将其留下并且仅使用 self.table_name ='discogs.disco',则似乎一切都可以正常工作...除了 database_cleaner。它使用 schema_search_path 来从模式获取表列表。如果我省略了这个步骤,并且在测试运行之间记录保持堆积在被省略的模式表中。 - Foton
我尝试了相同的方法,但是我无法访问DiscoGsSchema的活动存储记录。例如:User表只存在于PublicSchema中,然后我尝试执行User.first.image,它仍在PublicSchema中检查,而不是在DiscoGsSchema中。但是,我可以从PublicSchema获取一个User记录,但无法获取存储在S3中的Active storage图像。请查看以下链接以获取详细说明: 链接 - praveen ak
如何pd_dump public_schema和discogs_schema - wiwit

20

14

在迁移中:

class CreateUsers < ActiveRecord::Migration
  def up
    execute 'CREATE SCHEMA settings'
    create_table 'settings.users' do |t|
      t.string :username
      t.string :email
      t.string :password

      t.timestamps null: false
    end
  end

  def down
    drop_table 'settings.users'
    execute 'DROP SCHEMA settings'
  end

end

模型中的可选项

class User < ActiveRecord::Base
  self.table_name 'settings.users'
end

13

只需要这样做

class Foo < ActiveRecord::Base
  self.table_name = 'myschema.foo'
end

弃用set_table_name,改用self.table_name= https://github.com/rails/rails/commit/0b72a04 - Edgar Ortega

12

由于 set_table_name 已被移除,取而代之的是 self.table_name

我认为你应该按照以下方式编写代码:

class Foo < ActiveRecord::Base
  self.table_name =  'myschema.foo'
end

5

方法set_table_name已被删除。 self.table_name正常工作。


1
class ApplicationRecord < ActiveRecord::Base
  primary_abstract_class

  # Set schema
  def self.schema(schema)
    self.table_name = "#{schema}.#{self.name.tableize}"
  end
end

class Foo < ApplicationRecord
  schema :myschema
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接