rails proyecto new myapp digitalocean datos crear configurar conexion conectar con ruby-on-rails postgresql schema multi-tenant

ruby-on-rails - proyecto - rails new myapp postgresql



Crear una aplicaciĆ³n multi-tenant utilizando esquemas y rieles de PostgreSQL (3)

Cosas que ya he descifrado

Estoy aprendiendo cómo crear una aplicación multi-tenant en Rails que sirve datos de diferentes esquemas en función de qué dominio o subdominio se utiliza para ver la aplicación.

Ya tengo algunas inquietudes respondidas:

  1. ¿Cómo se puede hacer que subdomain-fu también funcione con dominios? Aquí hay alguien que hizo la misma pregunta que te lleva a este blog .
  2. ¿Qué base de datos y cómo se estructurará? Aquí hay una excelente charla de Guy Naor , y una buena pregunta sobre PostgreSQL y esquemas .
  3. Ya sé que mis esquemas tendrán la misma estructura. Diferirán en la información que guardan. Entonces, ¿cómo se pueden ejecutar migraciones para todos los esquemas? Aquí hay una respuesta .

Esos tres puntos cubren muchas de las cosas generales que necesito saber. Sin embargo, en los siguientes pasos parece que tengo muchas formas de implementar las cosas. Espero que haya una manera mejor y más fácil.

Finalmente, a mi pregunta

Cuando un nuevo usuario se registra, puedo crear el esquema fácilmente. Sin embargo, ¿cuál sería la mejor y más fácil forma de cargar la estructura que el resto de los esquemas ya tienen? Aquí hay algunas preguntas / escenarios que pueden darle una mejor idea.

  1. ¿Debería pasarlo a un script de shell que vuelque el esquema público en uno temporal y lo vuelva a importar a mi base de datos principal (más o menos como dice Guy Naor en su video)? Aquí hay un resumen / script rápido que obtuve del #postgres útil en freenode . Si bien esto probablemente funcionará, tendré que hacer muchas cosas fuera de Rails, lo que me incomoda un poco ... lo que también me lleva a la siguiente pregunta.
  2. ¿Hay alguna manera de hacer esto directamente desde Ruby on Rails ? Al igual que crear un esquema de PostgreSQL, simplemente cargue el esquema de la base de datos de Rails (schema.rb, lo sé, es confuso) en ese esquema de PostgreSQL.
  3. ¿Hay alguna joya / complemento que ya tenga estas cosas? Métodos como "create_pg_schema_and_load_rails_schema (the_new_schema_name)". Si no hay ninguno, probablemente trabaje para hacer uno, pero dudo sobre lo bien probado que será con todas las partes móviles (especialmente si termino usando un script de shell para crear y administrar nuevos esquemas de PostgreSQL).

Gracias, y espero que no sea demasiado largo!


¿Hay alguna joya / complemento que ya tenga estas cosas?

pg_power proporciona esta funcionalidad para crear / eliminar esquemas PostgreSQL en la migración, como este:

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

También se ocupa de eliminar correctamente los esquemas en el archivo schema.rb.


Cambiar la línea 38 a:

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

Supongo que postgres está intentando buscar nombres de tabla existentes al cargar schema.rb y, dado que ha establecido que search_path solo contenga el nuevo esquema, falla. Esto, por supuesto, supone que todavía tiene el esquema público en su base de datos.

Espero que ayude.


Actualización 5 de diciembre de 2011

Gracias a Brad Robertson y su equipo, está la joya de Apartamento . Es muy útil y hace mucho trabajo pesado.

Sin embargo, si está jugando con los esquemas, le sugiero que sepa cómo funciona realmente. Familiarízate con la guía de Jerod Santo , para que sepas qué hace la gema del Apartamento más o menos.

Actualización 20 de agosto de 2011 11:23 GMT + 8

Alguien creó una publicación de blog y recorre todo este proceso bastante bien.

Actualización 11 de mayo de 2010 11:26 GMT + 8

Desde anoche pude obtener un método para trabajar que crea un nuevo esquema y carga schema.rb en él. No estoy seguro de si lo que estoy haciendo es correcto (parece funcionar bien, hasta ahora) pero al menos está un paso más cerca. Si hay una mejor manera, por favor avíseme.

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