tl;dr : In rails 7, why do db:schema:load
rake task depend on db:test:purge
one which has env_name: "test"
hardcoded?
First of all, don't worry, I'm not performing destructive operations against production databases, but I am targeting databases with a rails application while Rails.env
is "production". That being said, here is my use case (just to give some context, but the question stays the same for all rails applications, see tl;dr) :
- I am working on an 'on demand remote environment' feature for a rails application
- This rails application has several databases, some contain business data, and now we're adding others which contain purely technical data
- The on demand environment feature I am working on uses dedicated db clones for business data (coming from a reference environment), but only an empty postgres container for technical databases (for cost efficiency, copy on write clones don't cost much, but still more than a trashable container)
- When starting the postgres container, databases and users are created, but the databases are empty
- When an on demand environment is started, a first job is run which calls the
db:migrate
rake task on all databases (there are reasons for that which I won't explain here) - I am leveraging this job to push the db structure from the rails app to the technical databases we're adding by running the
db:schema:load:tech_db_1
rake task before anything else
So, when calling db:schema:load
on a rails application, some other rake tasks are called as dependencies before that. One of these is db:test:purge
(generated here for each db), and when you get into the details (here), you see that it depends itself on a check_protected_environments
task which will return a ProtectedEnvironmentError if Rails.env
is "production". Fair enough, however the error message tells you you can set DISABLE_DATABASE_ENVIRONMENT_CHECK=1
if you know what you're doing and want to go further, but if you do this, the db:test:purge
rake task will try to run against your test databases, because it has env_name: "test"
hardcoded. And while I can find good reasons for this to be hardcoded in the db:test:whatever
tasks, I don't understand why other tasks like db:schema:load
(but that's not the only one, db:setup
, db:reset
etc... also do) depend on others tasks which have an hardcoded environment. It seems to me the check_protected_environments
task is enough to prevent operational errors, and if it has a way to be passed through, then subsequent operations should work as expected (i.e. against the expected databases, not necessarily test ones).
The only workaround I could come with is to point my applications test databases configuration to the same coordinates as the ones I actually want to work with during this setup job. This has nothing to do with production so I don't fear any risk of anything, but it feels dirty to do this.
EDIT : I decided to fill an issue on rails repo, here. It has been closed as duplicate of this one.
I guess there is no clear answer to my question as of today and when an answer will arise, it will probably come from the linked issue.