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
Move calls on Base connection to methods for rake tasks #46270
Move calls on Base connection to methods for rake tasks #46270
Conversation
1d8a07e
to
09e0b72
Compare
Waiting for last week's Rails upgrade to be done to merge this. |
This PR aims to contain calls to `Base.connection` and `Base.establish_connection` in active record rake tasks and the migration code. In a follow up PR I will swap out the `Base` class for a temporary class which will allow us to stop clobbering `Base` in the active record rails tasks. This work is an important step to achieve moving away from Active Record's dependence on `Base.connection` and `Base.establish_connection`. The reliance on `Base.connection` is problematic for sharding support and calling `Base.establish_connection` in the Rake tasks (without any warning message) indicates it's ok for applications to do the same (outside these tasks, it's not). I've vetted the approach of swapping out `Base` for a temporary class in another branch but decided that it would be easier to demonstrate and contain the changes if I first contained these calls. The major changes in this PR are: * Contain `Base.connection` in `Tasks.migration_connection` and replace calls to each * Contain `Base.establish_connection` in `Tasks.establish_connection` and replace calls to each * Add a `with_temporary_connection_for_each` method for cases where we need to loop over each config and set the connection back afterwards * Add a `with_temporary_connection(db_config)` method for cases where we have one config but need to establish a new connection and set the old one back. * Update every place we were looping through configs to establish a connection with the new temporary connection methods. There are a lot of changes here but I've pulled out everything that didn't need to be in this commit into other PRs. Once this is merged, I'll create the next PR that replaces `Base` the new methods in `Tasks` with a temporary connection and then we will officially be no longer clobbering `Base` in these tasks. This also reduces complexity because we won't need to ensure we set `Base.connection` back at the end. Once that is working and all internal methods are using the new temp class I'll deprecate calls on `Base.connection` in these methods. Most applications just override the task but not the actual methods in `Tasks` so my hope is this will be smooth-ish. However, nothing will stop applications from still using `Base.connection` for a very long time if they still want to clobber.
09e0b72
to
901828f
Compare
Hello! I'm happy to file an issue if that would be preferable, and/or create a reproduction case in a public repo, but I thought I'd chime in here to start: I ran
If I change my Gemfile to pick from the commit prior to this one, CI still works, so I believe the issue is orginiated here. I've tried a few workarounds (
Thank you! |
Hey @trevorturk - can you make a reproduction? I can't really debug this without a way to reproduce and my local apps and Shopify all passed fine with this change. Also I'd prefer an issue so that if someone else has the problem it's more discoverable. Thanks! |
In rails#46270 it was reported that there were database errors when running the tests in an app. I set up a demo app to use parallel testing and was able to reproduce. The issue was that the `reconstruct_from_schema` method needs to use the `pool` and not the `connection` because the database might not exist yet and will raise an error. I don't know how to test this inside Rails but I verified this behavior in my demo app.
Thank you for this, and for all of your work improving Ruby/Rails, it's very much appreciated! 🥳 |
This PR aims to contain calls to
Base.connection
andBase.establish_connection
in active record rake tasks and the migration code. In a follow up PR I will swap out theBase
class for a temporary class which will allow us to stop clobberingBase
in the active record rails tasks.This work is an important step to achieve moving away from Active Record's dependence on
Base.connection
andBase.establish_connection
. The reliance onBase.connection
is problematic for sharding support and callingBase.establish_connection
in the Rake tasks (without any warning message) indicates it's ok for applications to do the same (outside these tasks, it's not).I've vetted the approach of swapping out
Base
for a temporary class in another branch but decided that it would be easier to demonstrate and contain the changes if I first contained these calls. The major changes in this PR are:Base.connection
inTasks.migration_connection
and replace calls to eachBase.establish_connection
inTasks.establish_connection
and replace calls to eachwith_temporary_connection_for_each
method for cases where we need to loop over each config and set the connection back afterwardswith_temporary_connection(db_config)
method for cases where we have one config but need to establish a new connection and set the old one back.There are a lot of changes here but I've pulled out everything that didn't need to be in this commit into other PRs.
Once this is merged, I'll create the next PR that replaces
Base
the new methods inTasks
with a temporary connection and then we will officially be no longer clobberingBase
in these tasks. This also reduces complexity because we won't need to ensure we setBase.connection
back at the end. Once that is working and all internal methods are using the new temp class I'll deprecate calls onBase.connection
in these methods. Most applications just override the task but not the actual methods inTasks
so my hope is this will be smooth-ish. However, nothing will stop applications from still usingBase.connection
for a very long time if they still want to clobber.Checklist
Before submitting the PR make sure the following are checked:
[Fix #issue-number]
main
(if not - rebase it).