Skip to content

Migrations may fail when using multiple databases #29

@dark-panda

Description

@dark-panda

Under certain circumstances, migrations can fail due to the way that ActiveRecord executes migrations. For instance, consider the following sort of set up when using multiple databases in a solid-esque sort of way using some of the Solid components:

defaults: &defaults
  adapter: postgresql

default_databases: &default_databases
  primary: &primary
    <<: *defaults
    database: app

  cable: &cable
    <<: *defaults
    database: cable
    migrations_paths: 'db/cable_migrate'

  cache: &cache
    <<: *defaults
    database: cache
    migrations_paths: 'db/cache_migrate'

SolidCache and SolidCable are then set up to use these separate databases alongside your main app.

When you run the migrations, ActiveRecord is going to basically set the connection on ActiveRecord::Base to each database separately depending on which set of migrations its running, but as it is currently, the migrations will fail when the ARV sections attempt to run in production due to the active database connection not being the primary connection. For instance, when the migrations for the cable and cache databases are run, ARV will still attempt to run its view creation process but will fail because the underlying tables will likely not exist in the other databases.

I considered a bunch of approaches but settled on a quick fix:

diff --git a/lib/active_record_views.rb b/lib/active_record_views.rb
index b7b485d..c22e355 100644
--- a/lib/active_record_views.rb
+++ b/lib/active_record_views.rb
@@ -65,6 +65,8 @@ module ActiveRecordViews
   end
 
   def self.create_view(base_connection, name, class_name, sql, options = {})
+    return unless base_connection.pool.db_config.configuration_hash.fetch(:activerecord_views, true)
+
     options = options.dup
     options.assert_valid_keys :dependencies, :materialized, :unique_columns
     options[:dependencies] = parse_dependencies(options[:dependencies])

This allows me to set a configuration option in database.yml to disable ARV for a particular database and then move along in the migrations.

Other options I considered were:

  • Detecting the presence of the ARV's tables in the database to see if it's "ARV-enabled"
  • Having separate paths for database-specific views in the case where you want to have views in multiple databases, much like how migrations_paths works

These sorts of options require a bit more thought and discussion than my quick workaround, so I'm putting this up for discussion to see what others think.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions