Skip to content

Instantly share code, notes, and snippets.

@horpto
Created October 19, 2020 12:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save horpto/2fec1ec3aa57fa4e48c7bbed90ef48f6 to your computer and use it in GitHub Desktop.
Save horpto/2fec1ec3aa57fa4e48c7bbed90ef48f6 to your computer and use it in GitHub Desktop.
pseudo fast_bulk_update
def fast_bulk_update(model, values, fields, batch_size=1000):
# pg_specific and only simple values
from psycopg2.extras import execute_values
model_name = model._meta.db_table
assert model_name != 'vals'
pk_field = model._meta.pk
fields = tuple(model._meta.get_field(field) for field in fields)
fields_expr = ','.join(field.attname for field in fields)
vals_expr = ','.join(f'vals.{field.attname}::{field.db_type(connection)}' for field in fields)
sql = f'''
UPDATE "{model_name}"
SET ({fields_expr}) = ({vals_expr})
FROM (VALUES %s) AS vals(id,{fields_expr})
WHERE vals.id = "{model_name}"."{pk_field.attname}"
'''
fields_with_pk = (pk_field,) + tuple(fields)
values = (
tuple(field.get_prep_value(getattr(v, field.attname)) for field in fields_with_pk)
for v in values
)
with connection.cursor() as cursor:
execute_values(cursor, sql, argslist=values, page_size=batch_size)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment