ActiveRecord::Migration.maintain_test_schema! doesn't work with structure.sql#15394
Conversation
|
I can confirm this issue. Have experienced it in my own applications. |
|
@senny @rafaelfranca I added PR that fixes the issue. Please, let me know if some parts can be improved. |
|
Got this issue as well. |
|
Confirm |
There was a problem hiding this comment.
do we need to create again? purge should already do that.
There was a problem hiding this comment.
This is not true for sqlite: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb#L17-L24
Maybe we should change purge on this adapter to create database as it is in pg and mysql?
There was a problem hiding this comment.
it should have the same semantics for sure. The description in the Rake task is: "Empty the test database"
To me this implies that the database still exists. Let's change the SQLite3 adapter.
|
@morgoth I am working on foreign key support for Rails 4.2. Once schema.rb will be able to create foreign key, we can no longer rely on |
|
@senny should I add |
|
@morgoth At this point I do think we should backport the purge for schema.rb as well. I've seen a couple of situations where the test db got out of sync and couldn't be fixed by the automatic maintenance. The last resort was to /cc @rafaelfranca |
|
@senny I updated PR with your suggeestions |
|
@morgoth thanks man 💛 I'll need some time to make sure we don't run into regressions. Will ping you back by tomorrow. |
There was a problem hiding this comment.
what promted the addition of this test? Is it actually failing when we remove the purge?
There was a problem hiding this comment.
Yes, exactly.
To see it failing we must change structure and try to load it to existing database.
There was a problem hiding this comment.
is this the absolute minimal test-case to reproduce the failure? There's much of overhead involved. Would be great if we can shrink it further to only guard against the purge case.
There was a problem hiding this comment.
I removed 2 lines, but it doesn't help much ;-).
I tried to follow user steps and I think it is minimal test case this way.
It would simplify if we create db with first version of structure.sql without all these steps, but I don't how to do that in this test.
…ure schema format. Additionally: * It changes `purge` task on `sqlite3` adapter to recreate database file, to be consistent with other adapters. * Adds `purge` step when loading from `schema.rb`
…-schema-for-sql-format ActiveRecord::Migration.maintain_test_schema! doesn't work with structure.sql Conflicts: activerecord/CHANGELOG.md
|
@morgoth thank you, this will solve my issues with foreign keys and makes the automatic schema maintenance more predictable. It will add ~100ms penalty when running the tests and the schema migration needs to be performed. As this only happens here and then I don't think this is a big issue. @rafaelfranca I'd like to backport this patch as is. This means the behavior for |
|
@senny 👍 for backporting to 4-1-stable as it is. @carlosantoniodasilva will be happy 😄 |
…-schema-for-sql-format ActiveRecord::Migration.maintain_test_schema! doesn't work with structure.sql Conflicts: activerecord/CHANGELOG.md Conflicts: activerecord/CHANGELOG.md
|
This PR breaks rake db:schema:load for MySQL for development and production. I will revert for now. |
|
@jonleighton might know what's going on. While thinking about it, this could also be related to spring. (just guessing though). |
…atic-maintaining-test-schema-for-sql-format"" This reverts commit 5c87b5c.
|
I don't know sorry. You can exclude spring by setting the |
Previously this method always established a connection to the test database. This resulted in buggy behavior when combined with other tasks like `bin/rake db:schema:load`. This was one of the reasons why #15394 (22e9a91) was reverted: > I’ve replicated it on a new app by the following commands: 1) rails generate model post:title, 2) rake db:migrate, 3) rake db:schema:load, 4) rails runner ‘puts Post.first’. The last command goes boom. Problem is that rake db:schema:load wipes the database, and then doesn’t actually restore it. This is all on MySQL. There’s no problem with SQLite. -- DHH 22e9a91#commitcomment-6834245
…maintaining-test-schema-for-sql-format"" This reverts commit 5c87b5c.
The rake tasks and the `DatabaseTakss` adapter classes used to assume a configuration at some places. This forced the rake tasks to establish a specific connection before calling into `load_schema`. After #15394 this started to cause issues because it could `purge` the wrong database before loading the schema.
…maintaining-test-schema-for-sql-format"" This reverts commit 5c87b5c.
The rake tasks and the `DatabaseTakss` adapter classes used to assume a configuration at some places. This forced the rake tasks to establish a specific connection before calling into `load_schema`. After #15394 this started to cause issues because it could `purge` the wrong database before loading the schema.
…maintaining-test-schema-for-sql-format"" This reverts commit 5c87b5c.
The rake tasks and the `DatabaseTakss` adapter classes used to assume a configuration at some places. This forced the rake tasks to establish a specific connection before calling into `load_schema`. After #15394 this started to cause issues because it could `purge` the wrong database before loading the schema.
|
@senny This will be fixed in 4.2? Here's a workaround for postgres users who want to use # Put in spec_helper, before call to ActiveRecord::Migration.maintain_test_schema!
if ActiveRecord::Migrator.needs_migration?
puts('Needs migrations, purging test database ..')
ActiveRecord::Tasks::PostgreSQLDatabaseTasks
.new(ActiveRecord::Base.configurations.fetch('test'))
.purge
end |
|
@jaredbeck yes, this is fixed on |
Previously this method always established a connection to the test database. This resulted in buggy behavior when combined with other tasks like `bin/rake db:schema:load`. This was one of the reasons why #15394 (22e9a91) was reverted: > I’ve replicated it on a new app by the following commands: 1) rails generate model post:title, 2) rake db:migrate, 3) rake db:schema:load, 4) rails runner ‘puts Post.first’. The last command goes boom. Problem is that rake db:schema:load wipes the database, and then doesn’t actually restore it. This is all on MySQL. There’s no problem with SQLite. -- DHH 22e9a91#commitcomment-6834245 Conflicts: activerecord/CHANGELOG.md
|
Watching this issue... in v4.2.0.beta2 I have noticed that my test db never get's populated due to |
All of the behavior :environment was giving (that db:schema:load needed) was provided as well with :load_config. This will address an issue introduced in rails#15394. The fact that db:schema:load now drops and creates the database causes the Octopus gem to have [an issue](thiagopradi/octopus#273) during the drop step for the test database (which wasn't happening in db:schema:load before). The error looks like: ActiveRecord::StatementInvalid: PG::ObjectInUse: ERROR: cannot drop the currently open database : DROP DATABASE IF EXISTS "app_test" Because of the timing, this issue is present in master, 4-2-*, and 4.1.8. A note to forlorn developers who might see this: "Additionally" in a commit message means you should have a separate commit, with a separate justification for changes. Small commits with big messages are your friends.
All of the behavior :environment was giving (that db:schema:load needed) was provided as well with :load_config. This will address an issue introduced in #15394. The fact that db:schema:load now drops and creates the database causes the Octopus gem to have [an issue](thiagopradi/octopus#273) during the drop step for the test database (which wasn't happening in db:schema:load before). The error looks like: ActiveRecord::StatementInvalid: PG::ObjectInUse: ERROR: cannot drop the currently open database : DROP DATABASE IF EXISTS "app_test" Because of the timing, this issue is present in master, 4-2-*, and 4.1.8. A note to forlorn developers who might see this: "Additionally" in a commit message means you should have a separate commit, with a separate justification for changes. Small commits with big messages are your friends.
All of the behavior :environment was giving (that db:schema:load needed) was provided as well with :load_config. This will address an issue introduced in rails#15394. The fact that db:schema:load now drops and creates the database causes the Octopus gem to have [an issue](thiagopradi/octopus#273) during the drop step for the test database (which wasn't happening in db:schema:load before). The error looks like: ActiveRecord::StatementInvalid: PG::ObjectInUse: ERROR: cannot drop the currently open database : DROP DATABASE IF EXISTS "app_test" Because of the timing, this issue is present in master, 4-2-*, and 4.1.8. A note to forlorn developers who might see this: "Additionally" in a commit message means you should have a separate commit, with a separate justification for changes. Small commits with big messages are your friends.
Introduced in rails 4.1.
Checked using sqlite3 and postgres.
At the end of calling
ActiveRecord::Migration.maintain_test_schema!this method is called:rails/activerecord/lib/active_record/tasks/database_tasks.rb
Line 159 in 99873ca
rails/activerecord/lib/active_record/tasks/sqlite_database_tasks.rb
Line 35 in 99873ca
So at the very end it runs:
sqlite3 db/test.sqlite3 < db/structure.sqlThis however can result in error like:
This error can happen when we created migration to add column to existing table.
It looks like it's necessary to always purge database before loading sql file and adding:
before line
rails/activerecord/lib/active_record/tasks/database_tasks.rb
Line 168 in 99873ca
I'm not sure if that is the best place however.
Similar issue was noted in #13528 (comment) by @kevintyll
Please, let me know if the issue is unclear, I can submit example app then.
If you think that's the correct way of fixing it, I can prepare a PR.
Addressing to @jonleighton as he is the author of this feature.