-
Notifications
You must be signed in to change notification settings - Fork 11.1k
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
[11.x] Add upsertUsing functionality #52405
Conversation
… is empty array, allow eloquent passthru
I guess I'm not fundmentally opposed to this but would need to work for other databases as well I think. |
That makes sense and I thought that might be the case! I'll work on adding it for the other databases that support upserts. |
@taylorotwell So SQLite warns about parsing ambiguity of So this produces an error: User::upsertUsing([
'name',
'email',
'password'
], function ($query) {
$query->selectRaw("'Test McTesterson' as name, email, password")
->from('users')
// notice no join conditions
->join('posts', fn ($join) => $join);
}, ['email'], [
'name'
]); But this does not: User::upsertUsing([
'name',
'email',
'password'
], function ($query) {
$query->selectRaw("'Test McTesterson' as name, email, password")
->from('users')
// notice no join conditions
->join('posts', fn ($join) => $join)
// but something comes between the join and the "on conflict" clause
->orderBy('users.id', 'desc');
}, ['email'], [
'name'
]); This also does not produce errors: User::upsertUsing([
'name',
'email',
'password'
], function ($query) {
$query->selectRaw("'Test McTesterson' as name, email, password")
->from('users')
// notice there are join conditions
->join('posts', 'users.id', 'posts.user_id');
}, ['email'], [
'name'
]); So it seems that running into this issue would be quite rare and I'm not sure it should be the responsibility of the ORM to protect the developer from making this mistake. Not to mention that trying to automatically append a |
Thanks for your pull request to Laravel! Unfortunately, I'm going to delay merging this code for now. To preserve our ability to adequately maintain the framework, we need to be very careful regarding the amount of code we include. If applicable, please consider releasing your code as a package so that the community can still take advantage of your contributions! |
Overview
This branch is based on an idea in the discussions - #46589
It adds an
upsertUsing
method which is similar to theinsertUsing
method and allows developers to upsert data using a subquery.I've implemented it only for MySql for now.
Benefits
Really it's an extension of
insertUsing
bringing the power of upserts. The alternative currently would be to either write a raw statement or to load records into memory and use the upsert method to enter them into the new table. Obviously, keeping it in MySQL is much faster and this method makes that easier to do for devs.My use case is syncing data from a staging table to the live table.
Breaking Changes
None! It's a new method and doesn't change any existing functionality!
Notes
One thing to note - I don't use the
laravel_upsert_alias
because it's difficult to implement with a subquery. I could nest the subquery like so:However, this would result in an error since the column
foo
doesn't exist in the subquery. If anyone has a good solution for this let me know! Although I'm not sure the alias would provide any benefit in this scenario anyway.