Currently the db:migrate
rake task runs dump
at the end which dumps the database structure to schema.rb
/ structure.sql
. This will be useful in development environment but I can’t see a reason why this should run in production environment. Removing this step in production would make deployments faster, I believe. Do others think that this should be fixed ?
I agree. Just yesterday, I wrote a separate task that only did migrations for deploy.
I occasionally run diff’s on the production schema.rb or structure.sql against what is in git to be sure development environments are staying in sync with production.
Seth, please correct me if I'm mistaken. Since the branch that gets deployed in production already has a structure.sql , we can always compare that with the development branches. What's the need for having a migration task prepare structure.sql in a production environment ?
Sorry if I wasn't clear before. Changes to structure.sql are only ever committed in development. When production runs a db:migrate it spits out a new version of structrue.sql. If I run a `git status` on production and see changes to structure.sql I know something is out of sync with the SCM deployed code and production. Ideally this would never happen, but I've helped out on projects where legacy columns were on production tables that were not reflected in the structure.sql file.
Does that clarify my use case?
Seth
Adding support for this in principle makes sense to me. Since we want the file to be generated in some environments an not in others, a generated flag would probably make sense. A flag could also support the use case explained by Seth, since he would just toggle it in config/environments/production.rb (say).
I agree, that’s what I had in mind too . How about a config named “generate_schema_after_migration” which holds true/false. It could be true by default, and you can override the default behavior by setting it to false in config/environments/production.rb
. I am ready to work on this if I get a green light.
Sounds good to me. The flag would be true by default for backwards compat, but newly generated apps would have it generated in the environment config files.
For new apps the generated flag assignment would assign to false in production.rb.
The value for the test environment is doubtful, but I think it is better not to generate the flag in test.rb. The reason is that generating the schema after running migrations is a responsibility of the development environment. In particular, you are not supposed to run migrations with RAILS_ENV=test. Therefore, having a flag related to migrations written in test.rb could send a confusing message in my view. If the test environment has nothing to do with migrations, why do I need to say anything about them in its config?
So, I believe for the test environment with can leave it at the implicit true default.
Xavier, you wrote that we are not supposed to run migrations with RAILS_ENV=test, but the Rails itself occasionally prompts us to do it.
For example, when I run rspec command having pending migrations on test environment, the Rails emits the following message:
Migrations are pending. To resolve this issue, run:
bin/rake db:migrate RAILS_ENV=test
This message is embedded in /activerecord/lib/active_record/migration.rb.
I am not sure if this message is a correct instruction or not, though.
Xavier, you wrote that we are not supposed to run migrations with
RAILS_ENV=test, but the Rails itself occasionally prompts us to do it.
For example, when I run rspec command having pending migrations on test environment, the Rails emits the following message:
> Migrations are pending. To resolve this issue, run: > > bin/rake db:migrate RAILS_ENV=test
This message is embedded in /activerecord/lib/active_record/migration.rb.
I am not sure if this message is a correct instruction or not, though.
I believe that message is not consistent with the golden path.
The big guidelines here are:
* Migrations run to evolve the schema. As a side-effect, running them generates db/schema.(rb|sql).
* The test environment should always start afresh, the test database is considered to be transient by design, gets trashed and rebuilt, and therefore has no evolutive maintenance.
* Because of that, the test environment setup is designed around db/schema.(rb|sql), not around migrations. You need to get db/schema.(rb|sql) right *first*, then run the suite.
* The interface to that workflow is encoded via rake tasks. The test environment setup loads the current schema. If you go always through rake tasks everything works out of the box as long as the schema is in sync with migrations. If it isn't, you need to run migrations in the development environment to update the schema (and to have an up to date schema in the development database of course).
* If for some reason you prefer not to go through rake tasks for running tests, that's a little deviation from the point of view of the Rails interface, but the point closer to the golden path is to load the schema by hand (db:schema:load), not to run migrations in the test environment.
So, yeah, from my perspective that message is not pointing in the right direction.
I agree, test environment should not evolve the schema, instead depend on an existing schema. So I think it makes sense not to generate schema if at all I choose to run migrations in the test environment.
For the archives, this has been merged
Comparing 7f648bc70e76...c0fb8d0b9c4d · rails/rails · GitHub
Thanks Emil!