Migrating from bulk_upsert
View SourceBulkinup is the continuation of the
bulk_upsert package: versions <= 0.5.x were released
as bulk_upsert, and 0.6.0 is the first release as bulkinup. The upsert behavior is
unchanged — for existing callers the migration is a rename.
1. Swap the dependency
In mix.exs:
# Before
{:bulk_upsert, "~> 0.5.0"}
# After
{:bulkinup, "~> 0.6.0"}Then mix deps.get. (All bulk_upsert versions are retired on Hex — they still resolve and
compile, but every deps.get warns until you switch.)
2. Rename the call
BulkUpsert.bulk_upsert/4 is now Bulkinup.upsert/4 — same arguments, same options, same
return shape:
# Before
BulkUpsert.bulk_upsert(YourProject.Repo, Person, attrs_list, opts)
# After
Bulkinup.upsert(YourProject.Repo, Person, attrs_list, opts){:ok, %{upserted: n, skipped: n}} is unchanged, so with/case matches on the return keep
working as-is.
3. (Optional) Replace a hand-rolled wrapper with use Bulkinup
If your repo module wraps the old call — the pattern the bulk_upsert README recommended —
consider use Bulkinup, which injects bulk_insert/3 and bulk_upsert/3 with app-wide
defaults declared once:
defmodule YourProject.Repo do
use Ecto.Repo,
otp_app: :your_project,
adapter: Ecto.Adapters.Postgres
use Bulkinup,
upsert: [replace_all_except: [:inserted_at]]
endDelete the wrapper first
use Bulkinup injects plain defs, so a module that still defines its own bulk_upsert/3
fails to compile. Delete the old wrapper function, then add use Bulkinup. Move any
defaults the wrapper hard-coded into the use options (see Bulkinup.__using__/1).
Two small things to watch while moving the wrapper's defaults:
use Bulkinupconventionally sits with the otheruselines, above the module'saliaslines — so fully qualify any module reference inside theuseoptions (an alias defined further down is not in effect there).- If the wrapper was the last user of an alias (or import), remove it too, or
mix compile --warnings-as-errorswill fail on the unused alias.
Log metadata
If you filter logs on the library's :reason metadata, two atoms were renamed with the
function:
:bulk_upsert_changeset_erroris now:upsert_changeset_error:bulk_upsert_items_skippedis now:upsert_items_skipped
(insert/4 uses :insert_changeset_error and :insert_items_skipped.)
What's new since 0.5.x
The rename repositions the library around nested bulk writes, with two sibling verbs:
Bulkinup.insert/4— pure bulk insert: no conflict defaults anywhere, duplicates raise.use Bulkinup— repo-scoped calls with compile-time-validated, app-wide defaults.
See the changelog for details.