-
-
Notifications
You must be signed in to change notification settings - Fork 115
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
Upsert #50
Comments
+1 on this useful feature. The Rust Diesel ORM has a upsert functionality when inserting/updating multiple rows. If there is a conflict on row it allows custom functionality on for that specific row using the |
Related The Vapor document seemed to indicate that
Once the |
|
Hmmm..., IF EXISTS (key …) /* ** e.g. ID in the SQL database ** */
UPDATE command /* update */
ELSE
INSERT command /* create */ ... seems that a variant of And BTW, a |
The SQL you pasted checks the db and decides whether to update or insert in a single query. The fact that this is an old SQL capability is not very helpful support for inclusion in Fluent. If you have specific examples of what problems you're trying to solve, ideas about how this could relate to the Model API (as @calebkleveter has done), or references to other ORMs similar to Fluent that include support (as @rnantes has done), that is much more helpful. Building this feature in a meaningful, easy-to-use way that is consistent with how the rest of Fluent works takes more effort than just adding in the SQL keywords. |
Here's an initial idea for API based on what @calebkleveter and @rnantes shared: let uuid = UUID()
// Insert user with name Foo
User(id: uuid, name: "Foo")
.create(on: db)
// Updates name to Bar
// Automatically uses same input values for the update
User(id: uuid, name: "Bar")
.create(orUpdate: .conflict(\.$id), on: db)
// Updates name to Qux
// User decides the input values in case of conflict
User(id: uuid, name: "Baz")
.create(orUpdate: .conflict(\.$id), on: db) {
$0.set(\.$name, to: "Qux")
}
// Updates name to Quuz
// The model API will use this query builder API internally
User.query(on: db)
.set(\.$id, to: uuid)
.set(\.$name, to: "Quuz")
.create(orUpdate: .conflict(\.$id), on: db) I also tried with user.create(orUpdate: .on(conflict: \.$id), on: db) |
Note from vapor/fluent-mysql-driver#153 that timestamps should be updated correctly during upsert. |
Hi, is this still planned for inclusion? |
This was implemented at the SQLKit layer in vapor/sql-kit#90, but support in the FluentKit layer has yet to be added. |
An upsert is when you run a query that checks for a the existence of an entity matching a given predicate. If a match is found, then the rows found will be updated with the data passed in. If a match is not found, a new row with the given data is created. I think having builtin support for this would be nice:
From what I have been able to find, all SQL databases support this sort of operation. MongoDB appears to support it also.
The text was updated successfully, but these errors were encountered: