You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I found a way to do bulk insert and update with sqlc and Postgres:
-- name: CreateAuthors :execINSERT INTO authors
SELECT unnest(@ids::bigint[]) AS id,
unnest(@names::text[]) AS name,
unnest(@bios::text[]) AS bio;
-- name: UpdateAuthors :execUPDATE authors AS a
SET name =tmp.name, bio =tmp.bioFROM (
SELECT unnest(@ids::bigint[]) AS id,
unnest(@names::text[]) AS name,
unnest(@bios::text[]) AS bio
) AS tmp
WHEREa.id=tmp.id;
It uses arrays to serialize multiple rows into 1 parameter and unnest to deserialize them in Postgres. You can see the generated code in the playground.
It felt a bit hacky, so I made a benchmark to ensure that it is working as expected:
BenchmarkCreateAuthor and BenchmarkUpdateAuthor measure the time it takes to insert or update an author. The BenchmarkCreateAuthorsN and BenchmarkUpdateAuthorsN uses the above code to group N authors into a query.
By looking at BenchmarkCreateAuthor and BenchmarkCreateAuthors1000, we can see that it takes the same amount of time to create 100 authors with an insert and 30000 authors with the above method.
If you want to try it, you can find the code of the benchmark here.
Reacted by Danny Hermes
Reacted by Brandur, Oscar Beaumont, Grant Dexter, Amir Ghaffari, nguyenhoai890, Kyle Gray, Rodolfo Silva, Lucas Bremgartner, Olivier Cano, ybert and 19 more
@aitva Does this solution also work for fields which are Nullable? Because right now when I am creating my inserts this way I get []int64 for ::bigInt[] but I need to have []sql.NullInt64 because this field is nullable? Any ideas on how this could work?
@aitva We have been using the json_populate_recordset function in order to do bulk inserts which does allow for null values. There are other json functions you may want to use like json_to_record. Unfortunately the models generated by sqlc do not work well with these methods as instead of using NullInt64 you would want int64 with omit empty
@Jille@kyleconroy, please consider reopening this issue to support the COPY instruction for bulk inserts with lib/pq, as originally mentioned above.
The documentation says:
The :copyfrom command requires either pgx/v4 or pgx/v5.
Activity
dharmjit commentedon Mar 11, 2020
Hi @kyleconroy, Any update on this.
kyleconroy commentedon Mar 11, 2020
Nope, no update as of yet. It's low on my list, as I'm focusing on MySQL / SQLite support right now.
fr3fou commentedon Apr 12, 2021
Hi! Any updates on this?
aitva commentedon Apr 29, 2021
I found a way to do bulk insert and update with sqlc and Postgres:
It uses arrays to serialize multiple rows into 1 parameter and
unnestto deserialize them in Postgres. You can see the generated code in the playground.It felt a bit hacky, so I made a benchmark to ensure that it is working as expected:
BenchmarkCreateAuthorandBenchmarkUpdateAuthormeasure the time it takes to insert or update an author. TheBenchmarkCreateAuthorsNandBenchmarkUpdateAuthorsNuses the above code to groupNauthors into a query.By looking at
BenchmarkCreateAuthorandBenchmarkCreateAuthors1000, we can see that it takes the same amount of time to create 100 authors with an insert and 30000 authors with the above method.If you want to try it, you can find the code of the benchmark here.
kyleconroy commentedon Aug 28, 2021
Now that pgx support has landed, we'll also need support their Copy Protocol.
nd291195 commentedon Nov 4, 2021
@aitva Does this solution also work for fields which are Nullable? Because right now when I am creating my inserts this way I get []int64 for ::bigInt[] but I need to have []sql.NullInt64 because this field is nullable? Any ideas on how this could work?
Jille commentedon May 9, 2022
https://docs.sqlc.dev/en/latest/howto/insert.html#using-copyfrom has landed, so I think we can close this.
ovadbar commentedon Dec 6, 2022
@aitva We have been using the json_populate_recordset function in order to do bulk inserts which does allow for null values. There are other json functions you may want to use like json_to_record. Unfortunately the models generated by sqlc do not work well with these methods as instead of using NullInt64 you would want int64 with omit empty
giulianopz commentedon Mar 11, 2024
@Jille @kyleconroy, please consider reopening this issue to support the COPY instruction for bulk inserts with lib/pq, as originally mentioned above.
The documentation says:
Jille commentedon Mar 11, 2024
Let's make that a new feature request. Would you mind coming that?
giulianopz commentedon Mar 11, 2024
Sure, I've just opened a new issue for it: #3264.