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
Adding bulk inserts or updates for PostgreSQL #226
Adding bulk inserts or updates for PostgreSQL #226
Conversation
* } | ||
* ``` | ||
* | ||
* @since 2.7 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vincentlauvlwj what version should go here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Next version 3.3.0
Thank you for your contribution!! One question: What's the difference between calling |
Also, please update the |
Good question, I haven't though about that scenario... But thinking about it now, I only see two possibilities: Given that this method is an Insert or Update, it will potentially never throw an error on finding duplicates with the given key columns (by design). And this behavior is probably enforced by PostgreSQL itself. So the developer using a query like: INSERT INTO $table ($col1, $col2, ...)
VALUES (...), (...), (...), ...
ON CONFLICT ($col1, $col2, ...)
DO UPDATE SET .... Must be aware that this will never return an error for the first-level "collision" of ($col1, $col2, ...). So, my conceptual line of though was the following; Given that when I use "upserts" I either want to:
So, to account for scenario 1 we can use the form: // Generates a DO UPDATE SET
onDuplicateKey(Employees.id) {
set(it.salary, it.salary + 900)
} For scenario 2 we can use the form: // Generates a DO NOTHING
onDuplicateKey(Employees.id) {
} For scenario 3, it cannot be done in this type of query as far as I understand by design of PostgreSQL. There's no way to throw an error if a record already exists matching the conflict columns I mention in the query.
This is all behavior that is native from PostgreSQL, given that there are only two actions we can do in these type of queries (NOTHING and UPDATE) according to their documentation. So, for scenario 3, the user should probably use the default Does this make sense to you? |
PS. I made some commits renaming these methods to make more clear what they do and what operation they represent (Insert or Update, i.e. Upsert). Also, what is the difference between a |
Thank you for the explanation, I fully understand what you mean. But would it be possible to generate an insert SQL without database.bulkInsert(Employees) {
item {
set(it.name, "jerry")
set(it.job, "trainee")
set(it.managerId, 1)
set(it.hireDate, LocalDate.now())
set(it.salary, 50)
set(it.departmentId, 1)
}
item {
set(it.name, "linda")
set(it.job, "assistant")
set(it.managerId, 3)
set(it.hireDate, LocalDate.now())
set(it.salary, 100)
set(it.departmentId, 2)
}
} Then generated SQL: INSERT INTO t_employee (name, job, manager_id, hire_date, salary, department_id)
VALUES (?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?) This is exactly the scenario 3 you mentioned, it inserts new records if not exists, and throws an error on collisions. |
If it is possible to make |
Ok, I get the idea, I didn't go that way because it didn't seem to be the way the code was designed initially, meaning that I will need to change this behavior to allow an empty "conflictTarget" to exist (remove that Is this behavior also intended on insertOrUpdate()? I am gonna assume "yes", so please let me know. I applied these changes, so that both I also added a TODO note on the tests, because I think some tests have overlapping ids, so maybe we should make sure each test generates unique (thread-safe) entry ids? Let me know what you think. I am still wondering if |
…ing the methods and updating the tests accordingly.
Merged, I will release v3.3.0 these days. |
|
You are right, the name Maybe it is better to have another function |
@vincentlauvlwj awesome! Keep up the great work! 💪 |
Adding support for PostgreSQL bulk insert or update (also allowing to bulk ignore conflicts).
(Will add +900 to each already existing employee salary)
(Will ignore any already existing employee and continue the query)