45

私がすでに理解したもの

アプリケーションの表示に使用されるドメインまたはサブドメインに基づいて、さまざまなスキーマからのデータを提供するマルチテナントアプリケーションをRailsで作成する方法を学習しています。

私はすでにいくつかの懸念に答えています:

  1. subdomain-fuをドメインでも機能させるにはどうすればよいですか?これは、このブログにつながる同じ質問をした人です。
  2. どのデータベース、そしてそれはどのように構成されますか?これはGuyNaorによる素晴らしい講演であり、PostgreSQLとスキーマについての良い質問です。
  3. スキーマがすべて同じ構造になることはすでに知っています。保持するデータが異なります。では、どのようにしてすべてのスキーマの移行を実行できますか?これが答えです。

これらの3つのポイントは、私が知る必要のある一般的なことの多くをカバーしています。しかし、次のステップでは、物事を実装する方法がたくさんあるようです。より良い、より簡単な方法があることを願っています。

最後に、私の質問に

新しいユーザーがサインアップすると、スキーマを簡単に作成できます。ただし、残りのスキーマにすでにある構造をロードするための最良かつ最も簡単な方法は何でしょうか。ここにあなたにもっと良い考えを与えるかもしれないいくつかの質問/シナリオがあります。

  1. パブリックスキーマを一時的なスキーマにダンプし、それをメインデータベースにインポートするシェルスクリプトに渡す必要がありますか(Guy Naorが彼のビデオで言っていることとほとんど同じです)?これは、freenodeの役立つ#postgresから得た簡単な要約/スクリプトです。これはおそらくうまくいくでしょうが、私はRailsの外で多くのことをしなければならないでしょう、それは私を少し不快にします..それはまた私を次の質問に連れて行きます。
  2. これをRubyonRailsから直接行う方法はありますか?PostgreSQLスキーマを作成するのと同じように、Railsデータベーススキーマ(schema.rb-わかりにくいです)をそのPostgreSQLスキーマにロードするだけです。
  3. これらのものをすでに持っている宝石/プラグインはありますか?「create_pg_schema_and_load_rails_schema(the_new_schema_name)」のようなメソッド。ない場合は、おそらく作成に取り組みますが、すべての可動部分でどれだけうまくテストできるかについては疑問です(特に、シェルスクリプトを使用して新しいPostgreSQLスキーマを作成および管理する場合)。

ありがとう、そして私はそれがそれほど長くなかったことを望みます!

4

3 に答える 3

12

2011年12月5日更新

ブラッド・ロバートソンと彼のチームのおかげで、アパートの宝石があります。それは非常に便利で、多くの重労働を行います。

ただし、スキーマをいじくり回す場合は、スキーマが実際にどのように機能するかを知っておくことを強くお勧めします。Jerod Santoのウォークスルーをよく 理解して、アパートの宝石が多かれ少なかれ何をしているのかを理解してください。

更新2011年8月20日11:23GMT+ 8

誰かがブログ投稿を作成し、このプロセス全体をかなりうまく歩きます。

2010年5月11日11:26GMT+8更新

昨夜から、新しいスキーマを作成してそれにschema.rbをロードするメソッドを機能させることができました。私がしていることが正しいかどうかはわかりませんが(これまでのところうまく機能しているようです)、少なくとも一歩近づいています。もっと良い方法があれば教えてください。


  module SchemaUtils
   def self.add_schema_to_path(schema)
    conn = ActiveRecord::Base.connection
    conn.execute "SET search_path TO #{schema}, #{conn.schema_search_path}"
   end

   def self.reset_search_path
    conn = ActiveRecord::Base.connection
    conn.execute "SET search_path TO #{conn.schema_search_path}"
   end

   def self.create_and_migrate_schema(schema_name)
    conn = ActiveRecord::Base.connection

    schemas = conn.select_values("select * from pg_namespace where nspname != 'information_schema' AND nspname NOT LIKE 'pg%'")

    if schemas.include?(schema_name)
     tables = conn.tables
     Rails.logger.info "#{schema_name} exists already with these tables #{tables.inspect}"
    else
     Rails.logger.info "About to create #{schema_name}"
     conn.execute "create schema #{schema_name}"
    end

    # Save the old search path so we can set it back at the end of this method
    old_search_path = conn.schema_search_path

    # Tried to set the search path like in the methods above (from Guy Naor)
    # [METHOD 1]: conn.execute "SET search_path TO #{schema_name}"
    # But the connection itself seems to remember the old search path.
    # When Rails executes a schema it first asks if the table it will load in already exists and if :force => true. 
    # If both true, it will drop the table and then load it. 
    # The problem is that in the METHOD 1 way of setting things, ActiveRecord::Base.connection.schema_search_path still returns $user,public.
    # That means that when Rails tries to load the schema, and asks if the tables exist, it searches for these tables in the public schema.
    # See line 655 in Rails 2.3.5 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
    # That's why I kept running into this error of the table existing when it didn't (in the newly created schema).
    # If used this way [METHOD 2], it works. ActiveRecord::Base.connection.schema_search_path returns the string we pass it.
    conn.schema_search_path = schema_name

    # Directly from databases.rake. 
    # In Rails 2.3.5 databases.rake can be found in railties/lib/tasks/databases.rake
    file = "#{Rails.root}/db/schema.rb"
    if File.exists?(file)
     Rails.logger.info "About to load the schema #{file}"
     load(file)
    else
     abort %{#{file} doesn't exist yet. It's possible that you just ran a migration!}
    end

    Rails.logger.info "About to set search path back to #{old_search_path}."
    conn.schema_search_path = old_search_path
   end
  end
于 2010-10-29T13:19:32.823 に答える
3

38行目を次のように変更します。

conn.schema_search_path = "#{schema_name}, #{old_search_path}"

postgresはschema.rbをロードするときに既存のテーブル名を検索しようとしていると思いますが、search_pathを新しいスキーマのみを含むように設定しているため、失敗します。もちろん、これは、データベースにまだパブリックスキーマがあることを前提としています。

お役に立てば幸いです。

于 2011-03-18T08:42:06.013 に答える
0

これらのものをすでに持っている宝石/プラグインはありますか?

pg_powerは、次のように、移行時にPostgreSQLスキーマを作成/削除するためのこの機能を提供します。

def change
  # Create schema
  create_schema 'demography'

  # Create new table in specific schema
  create_table "countries", :schema => "demography" do |t|
    # columns goes here
  end

  # Drop schema
  drop_schema 'politics'
end

また、schema.rbファイルにスキーマを正しくダンプすることにも注意を払います。

于 2013-08-14T09:32:09.370 に答える