Skip to content

Loading…

db:schema:load with migrations in subdirectories #14012

Open
wants to merge 1 commit into from

4 participants

@d-unseductable

Getting pending migrations errors after running

$ rake db:schema:load

when db/migrate directory contains any migrations in its subdirectories.

Example directories structure:

db/
    migrate/
        archive/
            1_create_people.rb
            2_add_age_to_people.rb
        3_add_phone_number_to_people.rb

If the db/migrate directory contains any migrations in its subdirectories, their versions are not inserted into schema_migrations table.

As for the example above, ActiveRecord::ConnectionAdapters::SchemaStatements.assume_migrated_upto_version method inserts only the 3rd version into the schema_migrations table.
But ActiveRecord::Migrator.migrations method expects the table to include all of the 3 versions. 1 and 2 are perceived as pending and this fact causes the pending migrations error.

The assume_migrated_upto_version fetched migrations files using

paths = migrations_paths.map {|p| "#{p}/[0-9]*_*.rb" }

So there was no subdirectories support.
The behaviour is fixed by

paths = migrations_paths.map {|p| "#{p}/**/[0-9]*_*.rb" }

Added a test case.

@andreychernih

We're getting the same problems. Any plans to get this merged?

@rafaelfranca rafaelfranca self-assigned this
@d-unseductable

Hi @rafaelfranca !

I rebased the branch, ready to merge.

@d-unseductable d-unseductable db:schema:load with migrations in subdirectories
Example directories structure:
    db/
      migrate/
        archive/
          1_create_people.rb
          2_add_age_to_people.rb
        3_add_phone_number_to_people.rb

If the db/migrate directory contains any migrations in its
subdirectories, their versions are not inserted into schema_migrations
table.

As for the example above,
ActiveRecord::ConnectionAdapters::SchemaStatements
  .assume_migrated_upto_version
method inserts only the 3rd version into the schema_migrations table.
But
ActiveRecord::Migrator.migrations
method expects the table to include all of the 3 versions. 1 and 2 are
perceived as pending and this fact causes the pending migrations error.

The assume_migrated_upto_version fetched migration files using
    paths = migrations_paths.map {|p| "#{p}/[0-9]*_*.rb" }
So there were no subdirectories support.
The behaviour is fixed by
    paths = migrations_paths.map {|p| "#{p}/**/[0-9]*_*.rb" }
Added a test case.
fa76905
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 27, 2015
  1. @d-unseductable

    db:schema:load with migrations in subdirectories

    d-unseductable committed
    Example directories structure:
        db/
          migrate/
            archive/
              1_create_people.rb
              2_add_age_to_people.rb
            3_add_phone_number_to_people.rb
    
    If the db/migrate directory contains any migrations in its
    subdirectories, their versions are not inserted into schema_migrations
    table.
    
    As for the example above,
    ActiveRecord::ConnectionAdapters::SchemaStatements
      .assume_migrated_upto_version
    method inserts only the 3rd version into the schema_migrations table.
    But
    ActiveRecord::Migrator.migrations
    method expects the table to include all of the 3 versions. 1 and 2 are
    perceived as pending and this fact causes the pending migrations error.
    
    The assume_migrated_upto_version fetched migration files using
        paths = migrations_paths.map {|p| "#{p}/[0-9]*_*.rb" }
    So there were no subdirectories support.
    The behaviour is fixed by
        paths = migrations_paths.map {|p| "#{p}/**/[0-9]*_*.rb" }
    Added a test case.
This page is out of date. Refresh to see the latest.
View
19 activerecord/CHANGELOG.md
@@ -1,3 +1,22 @@
+* Insert all the migrations' versions into schema_migrations table when
+ running db:schema:load.
+
+ Load all the migrations' versions from db/migrate directory and its
+ subdirectories to avoid pending migrations errors.
+
+ Fix ActiveRecord::ConnectionAdapters::SchemaStatements
+ .assume_migrated_upto_version method
+
+ Before:
+
+ paths = migrations_paths.map {|p| "#{p}/[0-9]*_*.rb" }
+
+ After:
+
+ paths = migrations_paths.map {|p| "#{p}/**/[0-9]*_*.rb" }
+
+ *Dmitry Gritsay*
+
* Revert behavior of `db:schema:load` back to loading the full
environment. This ensures that initializers are run.
View
2 activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -841,7 +841,7 @@ def assume_migrated_upto_version(version, migrations_paths = ActiveRecord::Migra
sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)
migrated = select_values("SELECT version FROM #{sm_table}").map(&:to_i)
- paths = migrations_paths.map {|p| "#{p}/[0-9]*_*.rb" }
+ paths = migrations_paths.map {|p| "#{p}/**/[0-9]*_*.rb" }
versions = Dir[*paths].map do |filename|
filename.split('/').last.split('_').first.to_i
end
View
17 activerecord/test/cases/ar_schema_test.rb
@@ -126,5 +126,22 @@ def test_timestamps_without_null_set_null_to_false_on_add_timestamps
assert !@connection.columns(:has_timestamps).find { |c| c.name == 'created_at' }.null
assert !@connection.columns(:has_timestamps).find { |c| c.name == 'updated_at' }.null
end
+
+ def test_schema_loads_migrations_from_subdirectories
+ previous_migrations_path = ActiveRecord::Migrator.migrations_path
+ ActiveRecord::Migrator.migrations_path =
+ MIGRATIONS_ROOT + "/valid_with_subdirectories"
+
+ ActiveRecord::Schema.define(:version => 3) do
+ # No need to create columns
+ # Testing version numbers only
+ end
+
+ migrations = @connection.select_all "SELECT version FROM schema_migrations"
+ assert_equal 3, ActiveRecord::Migrator::current_version
+ assert migrations.all? { |m| %w(1 2 3).include?(m["version"]) }
+
+ ActiveRecord::Migrator.migrations_path = previous_migrations_path
+ end
end
end
Something went wrong with that request. Please try again.