-
Notifications
You must be signed in to change notification settings - Fork 11.2k
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 support for naming additional database connections #54162
Add support for naming additional database connections #54162
Conversation
… default connection
Thanks for submitting a PR! Note that draft PR's are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface. Pull requests that are abandoned in draft may be closed due to inactivity. |
What's wrong with naming additional connections under There is already is a framework/src/Illuminate/Database/Eloquent/Model.php Lines 44 to 49 in 61492a8
|
@shaedrich This pattern is particularly useful when managing database connections across different environments. For example, when using a Redshift Datawarehouse in production but local and tests with a replica of the DWH in Sqlite. Additionally, I find it helpful to maintain a clear distinction between the functional naming (what the database represents in the business context) and the technical naming (the database type and provider).
Using name
|
You can name the connections under It's not at all bound to the database type and provider, and does exactly what you want. |
Additionally, to what @NickSdot said: The naming of the connections is a little misleading or redundant. They are named after their database types but they didn't have to be. It would suffice, supplying this as a config option. Also, what you suggest adding can be added to your own code without changing the framework fairly easy. |
I've been using named connections for years, not sure this PR adds that one cannot already do. <?php // config/database.php
return [
'default' => \env('DB_CONNECTION', 'mysql'),
'connections' => [
'reports' => [
'driver' => 'sqlite',
// ...
],
'mysql' => [
'driver' => 'mysql',
// ...
],
'logs' => [
'driver' => 'mysql',
// ...
],
],
// ...
]; Usage is mostly the same as it is in OP's examples, both on Models and on The Maybe there is a confusion regarding connection names and database drivers? |
Regarding switching database drivers depending on the environment, that can be done through environment variables, or by using a <?php // config/database.php
return [
'default' => \env('DB_CONNECTION', 'mysql'),
'connections' => [
'dwh' => match (env('APP_ENV', 'local')) {
'production' => [
'driver' => 'redshift',
// ... additional connection parameters
],
default => [
'driver' => 'sqlite',
// ... additional connection parameters
],
},
// ... other connections
],
]; Then you can just call |
I've been using the setup from my initial example for years with databases, broadcasting, and filesystems. The extra abstraction layer often gives me more flexibility when I know we'll need migrations or refactors in the future. Additionally, it provides the ability to use a different database technology locally (like sqlite), while still being able to quickly connect to a staging database if needed.
I can also solve this problem using @rodrigopedra approach, I'll definitely experiment with that. Currently, I often use a Trait with a nested config function and the result is the same. I personally find it a less elegant solution, but it works fine. So if no one sees value in this, I'm willing to close the PR. |
As someone who maintains an "Enterprise" Laravel app it is common to use multiple database connections as shown in the example with a I don't think it was mentioned but where this is really helpful is with testing. The application code may be like: |
@ejunker Please read the conversation. This is already possible. |
@shaedrich are you referring to the example that has a |
@ejunker Not just that. All the examples. There should be at least one that is fitting. |
I am not against this patch, just have a hard time reasoning over its benefits. Also, I found the wording used to "sell" this feature misleading, as this was not possible before ("Models can then specify which connection..."). But that might be a misinterpretation from my English skills, please take no offense. Specially as it basically adds another indirection, to read a config value that points to another config value. As @ejunker, I also maintain some "Enterprise" Laravel apps for a living, and all but one make use of different connections for several reasons. I, personally, find the use of the As a workaround, if one prefers this indirection over being explicit on their configuration, one can already use something like this: DB::connection(config('database.dwh'))->table('orders')->get();
|
@rodrigopedra I think this is more about making sure Laravel has good DX and ease of use rather than what it technically possible. Sure, for now I have to do |
This might also be a result of my non-native English skills. 😉 The intention is indeed not to make it sound like it’s about adding additional connections, but rather about introducing the extra abstraction layer over the database connections in an elegant way. |
@ejunker, the workaround I proposed was due to the comment where you found the proposed solution more "elegant" than using As I said before, I am not against this PR, and actually the changes are so little and localized, that, if you all think it has an appeal to it, I am all for it. I just don't share the same view on Laravel not providing "'first class' support for multiple database connections." or that the current support "is not a good developer experience and maybe not obvious to other developers that need to use multiple connections." It is even mentioned in the docs:
I also think it is an additional abstraction over connection and database drivers. I've seen much more confusion when using But again, if you all believe this is worth adding, I don't see a problem. |
And if one needs aliases, this can be as easy as this: <?php // config/database.php
$dwhConnectionConfig = [
'driver' => 'mysql',
// ...
];
return [
'default' => \env('DB_CONNECTION', 'mysql'),
'connections' => [
'reports' => [
'driver' => 'sqlite',
// ...
],
'mysql' => $dwhConnectionConfig,
'dwh' => $dwhConnectionConfig,
'my-other-connection' => $dwhConnectionConfig,
'logs' => [
'driver' => 'mysql',
// ...
],
],
// ...
]; |
@rodrigopedra I am mostly concerned about the improvements to being able to easily swap the database used during testing. If you look at the default <!-- <env name="DB_CONNECTION" value="sqlite"/> --> This allows you to easily swap to using the sqlite database for testing. But what if you have multiple connections? It would be nice to continue using the same pattern that Laravel introduced by doing something like this: <env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_CONNECTION_DWH" value="sqlite"/> This would configure it to use sqlite for both connections. Now, you can get that to work by doing Yes, it is a layer of indirection but so are Facades. This is almost like a Facade for a database connection and just like Facades make it easy to swap dependencies during testing, so does this. It seems that other developers are also running into this issue and having to invent their own solutions such as in this article: Database Unit Testing in Laravel with Multiple Connections |
Frankly I don't understand what this is allowing that you can't already do. |
This pull request introduces the ability to name multiple database connections, improving the developer experience when working with multiple databases. By providing meaningful names for each connection, it becomes more intuitive to switch between different databases.
This feature adds an abstraction layer that decouples the database implementation from your code by allowing you to define multiple named connections in the database configuration:
Models can then specify which connection to use via the $connection property:
Or you can use the connection directly in queries: