sql >> Database teknologi >  >> RDS >> PostgreSQL

Oprettelse af en multi-tenant-applikation ved hjælp af PostgreSQL's skemaer og Rails

Opdatering 5. december 2011

Takket være Brad Robertson og hans team er der Lejlighedsperlen . Det er meget nyttigt og gør meget ud af de tunge løft.

Men hvis du vil pille ved skemaer, foreslår jeg kraftigt, at du ved, hvordan det rent faktisk fungerer. Gør dig bekendt med Jerod Santos gennemgang , så du ved, hvad Apartment-perlen mere eller mindre laver.

Opdatering 20. august 2011 11:23 GMT+8

Nogen har oprettet et blogindlæg og går ret godt igennem hele denne proces.

Opdatering 11. maj 2010 11:26 GMT+8

Siden i går aftes har jeg været i stand til at få en metode til at fungere, der opretter et nyt skema og indlæser schema.rb i det. Ikke sikker på, om det, jeg gør, er korrekt (synes at fungere fint, indtil videre), men det er i det mindste et skridt nærmere. Hvis der er en bedre måde, så lad mig det vide.


  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


  1. MySQL større end eller lig med operatør ignorerer sin eller lig med forpligtelse

  2. php mysql sorter resultater efter rækkefølge hentet

  3. Lokale og globale midlertidige tabeller i SQL Server

  4. Hybrid OLTP/Analytics Database Workloads:Replikering af MySQL-data til ClickHouse