-
Notifications
You must be signed in to change notification settings - Fork 21.9k
Add db:prepare rake task. #35768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add db:prepare rake task. #35768
Conversation
It Creates the database, loads the schema, run the migrations and initializes with the seed data (use db:reset to also drop the database first). This rake task runs in an idempotent way ref rails#33139 (comment)
🙏🏻 This obviously isn't very mutli-DB aware, but it at least exposes an API that we'll be able to maintain when we fix that. 👌🏻 (@eileencodes may have stronger feelings on whether this can merge as is, or should grow that support first.) I have similar feelings about the implementation tbh.. just connecting then rescuing NoDatabaseError feels a bit rough, but I don't have any immediate better suggestion. (Though I have vague recollection there are cases where we don't actually get that exception -- if we can't connect at all [because the DB we asked for isn't there], we may not be able to tell why.) One thought would be to move the migrate to an We should add a couple of tests, covering the no DB, present-but-behind DB, and already-up-to-date DB cases -- but no need to get exhaustive: we can lean on the existing coverage of the underlying commands for details and edge cases. |
🤔 Doesn't this conflict with |
thanks @matthewd @simi, for your prompt feedback.
Ideally, I was thinking to call something like
@simi good catch, I know this is a hard question 😅 but do you have any naming suggestion? |
I looked at this and making it work for multiple db is pretty simple. We can looop through the configs, try to migrate and if we can't migrate run setup. I tested this on a local app by deleting one of the dbs in a multi-db app and not the others. Also I recommend the name New code would look like this: desc "Runs setup if database does not exist, or runs migrations if it does"
task construct: :load_config do
ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
ActiveRecord::Base.establish_connection(db_config.config)
begin
db_namespace["migrate"].invoke
rescue ActiveRecord::NoDatabaseError
db_namespace["setup"].invoke
end
end
end I think we can test this in the railties/test//application/rake/multi_dbs_test.rb for multiple databases and potentially also activerecord/test//cases/tasks/database_tasks_test.rb |
thanks much 🙇 @eileencodes, I gonna implement this suggestion and a couple of test cases on the files that you suggested |
Hmm... I like I also think it's hard to find an alternative that works for both the create and migrate use cases: e.g. you can definitely construct a database into existence, but I'm not sure about constructing an old database to bring it up to date. (I also also don't think giving this a different name fixes the potential for confusion with |
Agree with @matthewd, |
ede4850
to
6cefe76
Compare
6cefe76
to
098e4d2
Compare
2e9d168
to
900e566
Compare
Hi, 👋 I've test cases for multiple and single DB connection, Also I tested locally with a couple of rails apps and it's looking good. Could you please take a look again? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good but I think we need one more test. Can you add one that drops the db first and then runs prepare and makes sure that create and migrate are both run?
@eileencodes done 👍 |
@matthewd @guilleiguaran I'm ok with |
Thanks @robertomiranda! |
thanks a lot for all your help 🙇 |
oh actually, I have a question should we update the CHANGELOG? |
I think this change deserves changelog change. Feel free to open new PR @robertomiranda. |
* `rake db:prepare` looks to be equivalant. It runs the migration, if no database can be found it then seeks to create one. rails/rails#35768 * Given that this method is now tested as part of rails we have more confidence in the previous bug that reset the database despite it existing. Presumably this was caused by an error in how we were checking if a migration was pending so we should try removing our production guard.
* `rake db:prepare` looks to be equivalant. It runs the migration, if no database can be found it then seeks to create one. rails/rails#35768 * Given that this method is now tested as part of rails we have more confidence in the previous bug that reset the database despite it existing. Presumably this was caused by an error in how we were checking if a migration was pending so we should try removing our production guard.
If I understand correctly: this creates the DB if it doesn't exist, otherwise it runs migrations. Are you folks trying to abstract the fact that the database might not exist yet? It really seems like a dangerous idea: if you are running an app, you must know if you have a DB with data already or not. Once you know it, choosing one of two separate commands is trivial. Furthermore, if you don't know the difference between these two different states (creating the DB for the first time vs running migrations on an existing database) this can feel unpredictable, magic-like and overall confusing. |
* `rake db:prepare` looks to be equivalant. It runs the migration, if no database can be found it then seeks to create one. rails/rails#35768 * Given that this method is now tested as part of rails we have more confidence in the previous bug that reset the database despite it existing. Presumably this was caused by an error in how we were checking if a migration was pending so we should try removing our production guard.
* `rake db:prepare` looks to be equivalant. It runs the migration, if no database can be found it then seeks to create one. rails/rails#35768 * Given that this method is now tested as part of rails we have more confidence in the previous bug that reset the database despite it existing. Presumably this was caused by an error in how we were checking if a migration was pending so we should try removing our production guard.
* `rake db:prepare` looks to be equivalant. It runs the migration, if no database can be found it then seeks to create one. rails/rails#35768 * Given that this method is now tested as part of rails we have more confidence in the previous bug that reset the database despite it existing. Presumably this was caused by an error in how we were checking if a migration was pending so we should try removing our production guard.
* `rake db:prepare` looks to be equivalant. It runs the migration, if no database can be found it then seeks to create one. rails/rails#35768 * Given that this method is now tested as part of rails we have more confidence in the previous bug that reset the database despite it existing. Presumably this was caused by an error in how we were checking if a migration was pending so we should try removing our production guard.
In favor of getting merging #33139 (comment). I have implemented
rake db:prepare
which creates the database, loads the schema, run the migrations and initializes with the seed data(use db:reset to also drop the database first). This rake task runs in an idempotent way
cc @davidstosik @matthewd @guilleiguaran