influitive / apartment

Database multi-tenancy for Rack (and Rails) applications
2.68k stars 461 forks source link

is with_multi_server_setup not compatible with use_schemas? #640

Open NielsKSchjoedt opened 4 years ago

NielsKSchjoedt commented 4 years ago

I have an application that has been running with apartment with postgresql adapter in use_schemas-mode and it's been working for years. By tenants are based on country, splitting my application by country.

In order to scale the application we need to start splitting the database into multiple hosts (physical servers). I am trying to make this work using apartment, but so far it fails. I have an apartment config like this:

Apartment.configure do |config|
  config.excluded_models = ["User", "CustomerUser", "Payment::Order", "PaymentNotification", "Payment::OrderDiscount", "ModelText", "EmailResponse"]
  config.use_schemas = true
  config.use_sql = true
  config.persistent_schemas = ['extensions']
  config.prepend_environment = false
  config.append_environment = false

  config.default_schema = "da"
  tenant_config = {}
  {
    1111 => %w[de at se fi nl no],
    2222 => %w[it pl es pt ro da uk ch fr]
  }.each do |port, schemas|
    schemas.each do |tenant|
      tenant_config[tenant] = {
        adapter: 'postgresql',
        host: 'localhost',
        port: port,
        database: 'postgres' # this is not the name of the tenant's db
                             # but the name of the database to connect to, before creating the tenant's db
                             # mandatory in postgresql
      }
    end
  end

  config.with_multi_server_setup = true
  config.tenant_names = tenant_config
end

My database.yml looks like this:

common: &common
  adapter: postgresql
  encoding: utf8
  host: localhost
  port: 2222
  username: username
  password: password
  template: template0 # Required for UTF8 encoding
  schema_search_path: "da,extensions" # default_schema, persistent_schema

development:
  <<: *common
  database: my_app_testing
  pool: 10

staging:
  <<: *common
  database: my_app_staging
  pool: 40
  read_timeout: 10

test:
  <<: *common
  database: my_app_test
  pool: 10

profiling:
  <<: *common
  database: my_app_development
  pool: 10

production:
  <<: *common
  database: my_app_development
  pool: 10

Now when I try to do Apartment.switch!('de') I get:

Apartment::TenantNotFound: One of the following schema(s) is invalid: "de" "da", "extensions"
Caused by ActiveRecord::StatementInvalid: Could not find schema de

Why is this happening? Is there something I have overlooked?

BananaNeil commented 4 years ago

The research that I have done seems to indicate that use_schemas is incompatible with with_multi_server_setup

There is a note about it in this issue: https://github.com/influitive/apartment/issues/596, but I also went and traced through the code and found that use_schemas causes use of a different postgres adapter, which overrides the connect_to_new method.

I am in the same situation as you, and it is imparitive that my organization finds a solution to this issue. I will report back when I find a work around.

In the mean time, can we get some input from the maintainer ( @mikecmpbll ) about this issue?

Melaku05 commented 1 year ago

Steps to reproduce

I'm new here please help

Expected behavior

To run correctly

Actual behavior

Screenshot from 2023-09-26 18-54-00

Screenshot from 2023-09-26 19-04-13

System configuration

Apartment.configure do |config|

end

Rails.application.config.middleware.use Apartment::Elevators::Host



  * `use_schemas`: (`true` or `false`)

* Rails (or ActiveRecord) version:7.0.8

* Ruby version: 3.2.2