Package: django-fast-update
django-fast-updateFaster db updates usingUPDATE FROM VALUESsql variants.Installation & UsageRunpip install django-fast-updateand placefast_updatein INSTALLED_APPS.With attachingFastUpdateManageras a manager to your model,fast_updatecan be used instead ofbulk_update, e.g.:fromdjango.dbimportmodelsfromfast_update.queryimportFastUpdateManagerclassMyModel(models.Model):objects=FastUpdateManager()field_a=...field_b=...field_c=...# to update multiple instances at once:MyModel.objects.fast_update(bunch_of_instances,['field_a','field_b','field_c'])Alternativelyfast.fast_updatecan be used directly with a queryset as first argument
(Warning - this skips most sanity checks with up to 30% speed gain,
so make sure not to feed something totally off).Compatibilityfast_updateis known to work with these database versions:SQLite 3.15+PostgreSQLMariaDB 10.2+MySQL 5.7+For unsupported database backends or outdated versionsfast_updatewill fall back tobulk_update.
(It is possible to register fast update implementations for other db vendors withregister_implementation.
Seefast_update/fast.pyfor more details.)Note that withfast_updatef-expressions cannot be used anymore.
This is a design decision to not penalize update performance by some swiss-army-knife functionality.
If you have f-expressions in your update data, consider re-grouping the update steps and update those
fields withupdateorbulk_updateinstead.Other than withbulk_updateduplicates in a changeset are not allowed and will raise.
This is mainly a safety guard to not let slip through duplicates, where the final update state
would be undetermined or directly depend on the database's compatibility.copy_updateThis is a PostgreSQL only update implementation based onCOPY FROM. This runs even faster
thanfast_updatefor medium to big changesets (but tends to be slower thanfast_updatefor <100 objects).copy_updatefollows the same interface idea asbulk_updateandfast_update, minus abatch_sizeargument (data is always transferred in one big batch). It can be used likewise from theFastUpdateManager.copy_updatealso has no support for f-expressions, also duplicates will raise.Notecopy_updatewill probably never leave the alpha/PoC-state, as psycopg3 brings great COPY support,
which does a more secure value conversion and has a very fast C-version.NoteDjango 4.2 brings psycopg3 support, which is currently not yet supported bycopy_update.
While psycopg2 will keep working as before, psycopg3 will raise on attempts to usecopy_updateuntil #16 got resolved.StatusCurrently beta, still some TODOs left.The whole package is tested with Django 3.2 & 4.2 on Python 3.8 & 3.11.PerformanceThere is a management command in the example app testing performance of updates on theFieldUpdatemodel (./manage.py perf).fast_updateis at least 8 times faster thanbulk_update, and keeps making ground for bigger changesets.
This indicates different runtime complexity.fast_updategrows almost linear for very big numbers of rows
(tested during some perf series againstcopy_updateup to 10M), whilebulk_updategrows much faster
(looks quadratic to me, which can be lowered to linear by applying a properbatch_size,
but it stays very steep compared tofast_update).For very big changesetscopy_updateis the clear winner, and even shows a substantial increase in updated rows/s
(within my test range, as upper estimate this of course cannot grow slower than linear,
as the data pumping will saturate to linear).