def get_update_sql(self, rows):
        field_names = self.get_field_names()
        pk = field_names[0]
        update_field_names = field_names[1:]

        num_columns = len(rows[0])
        if num_columns < 2:
            raise Exception('At least 2 fields must be passed to get_update_sql')

        all_null_indices = [
            all(row[index] is None for row in rows)
            for index in range(1, num_columns)
        ]

        field_names_sql = '({0})'.format(', '.join(field_names))

        row_values = []
        sql_args = []

        for row in rows:
            placeholders = []
            for value in row:
                sql_args.append(value)
                placeholders.append('%s')
            row_values.append('({0})'.format(', '.join(placeholders)))
        row_values_sql = ', '.join(row_values)

        # build field list for SET portion
        set_field_list = [
            '{0} = NULL'.format(field_name)
            if all_null_indices[idx] else '{0} = new_values.{0}'.format(field_name)
            for idx, field_name in enumerate(update_field_names)
        ]
        set_field_list_sql = ', '.join(set_field_list)

        self.sql = 'UPDATE {0} SET {1} FROM (VALUES {2}) AS new_values {3} WHERE {0}.{4} = new_values.{4}'.format(
            self.tables[0].get_identifier(),
            set_field_list_sql,
            row_values_sql,
            field_names_sql,
            pk
        )

        return self.sql, sql_args
Parses a s7 error code returned the decorated function.
dataset/ETHPy150Open ambitioninc/django-query-builder/querybuilder/query.py/Query.get_update_sql--crossover with--dataset/ETHPy150Open gijzelaerr/python-snap7/snap7/partner.py/error_wrap