Question

BulkAttributeRenamer VS PythonCaller - Rename Attribute Names


Hi. I was trying to figure out a way to rename all the fields of my output shape using a PythonCaller. I used the "BulkAttributeRenamer" to rename the fields, but just using a single parameter as: prefix, sufix, lowercase, uppercase etc and it's not enough. When I tried to use PythonCaller, I could change only the attributes itself, but not their field's name (I used the function setAttribute(name, new_value))

Is there a python function that can set the AttributteName ?


15 replies

Userlevel 2
Badge +17

You can do something like this.

value = feature.getAttribute('old_name')
feature.setAttribute('new_name', value)
feature.removeAttribute('old_name')

Alternatively, you can call FME function "@RenameAttributes" with the "performFunction" method from FMEFeature class.

However, in most cases, the BulkAttributeRenamer could be a better solution, I think. What kind of renaming do you want?

Badge +4

I do this all the time to make some logic while bulk renaming attributes.

The following will do a casechange on all attributes except some.  

class BulkAttributeRenamer(object):
   
    def __init__(self):
        
        pass
    
    def startswith(self, prefixes, attr):
        for prefix in prefixes:
            if attr.startswith(prefix):
                return True
        return False 
    
    def input(self, feature):
        
        exluded_prefixes = ['fme_','geodb_','multi_']
        
        for name in feature.getAllAttributeNames():
            if self.startswith(exluded_prefixes, name):
                continue
            value = feature.getAttribute(name)
            feature.setAttribute(name.upper(), value)
            feature.removeAttribute(name)
        
        self.pyoutput(feature)
 
    def close(self):
        
        pass
 
    def process_group(self):
        
        pass

 

I do this all the time to make some logic while bulk renaming attributes.

The following will do a casechange on all attributes except some.  

class BulkAttributeRenamer(object):
   
    def __init__(self):
        
        pass
    
    def startswith(self, prefixes, attr):
        for prefix in prefixes:
            if attr.startswith(prefix):
                return True
        return False 
    
    def input(self, feature):
        
        exluded_prefixes = ['fme_','geodb_','multi_']
        
        for name in feature.getAllAttributeNames():
            if self.startswith(exluded_prefixes, name):
                continue
            value = feature.getAttribute(name)
            feature.setAttribute(name.upper(), value)
            feature.removeAttribute(name)
        
        self.pyoutput(feature)
 
    def close(self):
        
        pass
 
    def process_group(self):
        
        pass

 

@Paal Pedersen​ @Takashi Iijima​ This does not work.

 

To be fair, setAttribute  does work when I set the new attribute name in "Attributes to Expose" parameter. But removeAttribute never works. What it does is just making the attribute value missing (i.e. removing the value of that attribute), not removing the attribute itself.

 

I have also tried feature.performFunction('@RenameAttributes(newName,oldName)'). Same thing happened. All values under oldName attribute just went missing. The attribute still stay there.

 

Any idea how to truely remove the attributes? In my case, which attribute to be removed is unknown until runtime, so AttributeManager or BulkAttributeRemover is not helpful.

I do this all the time to make some logic while bulk renaming attributes.

The following will do a casechange on all attributes except some.  

class BulkAttributeRenamer(object):
   
    def __init__(self):
        
        pass
    
    def startswith(self, prefixes, attr):
        for prefix in prefixes:
            if attr.startswith(prefix):
                return True
        return False 
    
    def input(self, feature):
        
        exluded_prefixes = ['fme_','geodb_','multi_']
        
        for name in feature.getAllAttributeNames():
            if self.startswith(exluded_prefixes, name):
                continue
            value = feature.getAttribute(name)
            feature.setAttribute(name.upper(), value)
            feature.removeAttribute(name)
        
        self.pyoutput(feature)
 
    def close(self):
        
        pass
 
    def process_group(self):
        
        pass

 

Update: Writing to JSON worked, i.e. attributes where all values are missing were not written to the JSON file. However, this is not the desired output.

 

Have tried writing to Excel, csv, Esri geodatabase. Attributes where all values are missing were still present in the output, although they have no value (Excel, csv) or Null value (geodatabase).

 

A workaround could be writting to JSON first, then run another workbench to convert the data to Excel (desired output) but it would be great if all can be done in one run.

Badge +4

@Paal Pedersen​ @Takashi Iijima​ This does not work.

 

To be fair, setAttribute does work when I set the new attribute name in "Attributes to Expose" parameter. But removeAttribute never works. What it does is just making the attribute value missing (i.e. removing the value of that attribute), not removing the attribute itself.

 

I have also tried feature.performFunction('@RenameAttributes(newName,oldName)'). Same thing happened. All values under oldName attribute just went missing. The attribute still stay there.

 

Any idea how to truely remove the attributes? In my case, which attribute to be removed is unknown until runtime, so AttributeManager or BulkAttributeRemover is not helpful.

It most definitely do work. I guess youre looking for the attributes in the inspector, but cant see any? Well they are not exposed.

Badge +4

@Paal Pedersen​ @Takashi Iijima​ This does not work.

 

To be fair, setAttribute does work when I set the new attribute name in "Attributes to Expose" parameter. But removeAttribute never works. What it does is just making the attribute value missing (i.e. removing the value of that attribute), not removing the attribute itself.

 

I have also tried feature.performFunction('@RenameAttributes(newName,oldName)'). Same thing happened. All values under oldName attribute just went missing. The attribute still stay there.

 

Any idea how to truely remove the attributes? In my case, which attribute to be removed is unknown until runtime, so AttributeManager or BulkAttributeRemover is not helpful.

«Attributes to hide»

Badge +4

@Paal Pedersen​ @Takashi Iijima​ This does not work.

 

To be fair, setAttribute does work when I set the new attribute name in "Attributes to Expose" parameter. But removeAttribute never works. What it does is just making the attribute value missing (i.e. removing the value of that attribute), not removing the attribute itself.

 

I have also tried feature.performFunction('@RenameAttributes(newName,oldName)'). Same thing happened. All values under oldName attribute just went missing. The attribute still stay there.

 

Any idea how to truely remove the attributes? In my case, which attribute to be removed is unknown until runtime, so AttributeManager or BulkAttributeRemover is not helpful.

when it says missing, it means the attribute is missing.

@Paal Pedersen​ @Takashi Iijima​ This does not work.

 

To be fair, setAttribute does work when I set the new attribute name in "Attributes to Expose" parameter. But removeAttribute never works. What it does is just making the attribute value missing (i.e. removing the value of that attribute), not removing the attribute itself.

 

I have also tried feature.performFunction('@RenameAttributes(newName,oldName)'). Same thing happened. All values under oldName attribute just went missing. The attribute still stay there.

 

Any idea how to truely remove the attributes? In my case, which attribute to be removed is unknown until runtime, so AttributeManager or BulkAttributeRemover is not helpful.

Hi @Paal Pedersen​ , please see my other comments for clarification.

This is what I see in the inspector:

image 

And this is what I get in the output Excel file:

imageWhat I want to achieve is those attributes containing only missing value (like accountcategorycode and customersizecode in the photo) are not written to the Excel output. This is not achievable with feature.removeAttribute(name) as this function only makes all values under this attribute missing.

 

However, this probably can be achieved with "Attributes to hide" parameter in PythonCaller. Unfortunately, there's no way I can specify which attributes to expose or which attribute to hide in PythonCaller, as these are unknown until runtime.

Userlevel 1
Badge +10

Update: Writing to JSON worked, i.e. attributes where all values are missing were not written to the JSON file. However, this is not the desired output.

 

Have tried writing to Excel, csv, Esri geodatabase. Attributes where all values are missing were still present in the output, although they have no value (Excel, csv) or Null value (geodatabase).

 

A workaround could be writting to JSON first, then run another workbench to convert the data to Excel (desired output) but it would be great if all can be done in one run.

The issue is with your writer, if you have the attributes named in the writer they will be written whether they are missing or not. If you only want attributes present to be written then you will need to look at dynamic workflows

 

https://community.safe.com/s/article/dynamic-workflow-tutorial-introduction

Update: Writing to JSON worked, i.e. attributes where all values are missing were not written to the JSON file. However, this is not the desired output.

 

Have tried writing to Excel, csv, Esri geodatabase. Attributes where all values are missing were still present in the output, although they have no value (Excel, csv) or Null value (geodatabase).

 

A workaround could be writting to JSON first, then run another workbench to convert the data to Excel (desired output) but it would be great if all can be done in one run.

Which dynamic workflow would you suggest in my case? After a quick scan through the tutorial, it seems like none of them helps. Just for clarification, I have no idea which attributes will be written until runtime (that's why I need a PythonCaller to determine which one to be written), so any hard-wired approaches where, before running the workbench, you need to specify the exact attributes to be written will not work.

 

Or this is just unachievable within one workbench? As I mentioned in another comment, a workaround could be writing to JSON in one workbench (where all attributes containing only missing value are magically not included in the output JSON file), then running another workbench to convert that JSON to the desired format (Excel file in my case).

Badge +4

Update: Writing to JSON worked, i.e. attributes where all values are missing were not written to the JSON file. However, this is not the desired output.

 

Have tried writing to Excel, csv, Esri geodatabase. Attributes where all values are missing were still present in the output, although they have no value (Excel, csv) or Null value (geodatabase).

 

A workaround could be writting to JSON first, then run another workbench to convert the data to Excel (desired output) but it would be great if all can be done in one run.

Theres actually alot of ways to edit schema dynamically.

 

To understand the dynamic schema, try reading a dataset with a featureReader the inspect the attributes of a schema feature.

 

It has 3 list, attributes{}.name, attributes{}.fme_data_type, and attributes{}.native_data_type.

attributes{}.name conatines all the names of attributes the dynamic writer will use. The other two will im combination set the correct data-type.

Some writer need the native_data_type, others will work perfectly with only fme_data_type.

 

There is a custom transformer called SchemaSetter which can populate schema directly. Use this after the python attribute renamer and use a featureWriter with dynamic writer. I guess this will solve your problem.

Badge +4

Update: Writing to JSON worked, i.e. attributes where all values are missing were not written to the JSON file. However, this is not the desired output.

 

Have tried writing to Excel, csv, Esri geodatabase. Attributes where all values are missing were still present in the output, although they have no value (Excel, csv) or Null value (geodatabase).

 

A workaround could be writting to JSON first, then run another workbench to convert the data to Excel (desired output) but it would be great if all can be done in one run.

Use schemaScanner its from safe, and its better.

Update: Writing to JSON worked, i.e. attributes where all values are missing were not written to the JSON file. However, this is not the desired output.

 

Have tried writing to Excel, csv, Esri geodatabase. Attributes where all values are missing were still present in the output, although they have no value (Excel, csv) or Null value (geodatabase).

 

A workaround could be writting to JSON first, then run another workbench to convert the data to Excel (desired output) but it would be great if all can be done in one run.

Still have no idea how SchemaSetter can remove unwanted attributes that are unknown until runtime. Could you elaborate, please? The transformer has "Attributes to exclude" parameter, but it's just pretty much similar to "Attributes to hide" in PythonCaller which does not help in my case as I have no idea which attributes to remove until runtime.

 

My ultimate goal is to remove all attributes that contain only one value across the input table. For example, if attribute "country" is the same for all input features (let say they're all from the U.S.), the output table should not have attribute "country". My input table is a live table, it's got updated constantly. So if tomorrow there's one feature added to the input table with country = UK, the output table will have the attribute "country".

Badge +4

Update: Writing to JSON worked, i.e. attributes where all values are missing were not written to the JSON file. However, this is not the desired output.

 

Have tried writing to Excel, csv, Esri geodatabase. Attributes where all values are missing were still present in the output, although they have no value (Excel, csv) or Null value (geodatabase).

 

A workaround could be writting to JSON first, then run another workbench to convert the data to Excel (desired output) but it would be great if all can be done in one run.

Do some tutorials on the subject, if you only gonna answer instead of trying. You dont need to understand know, just focus on getting it to work. Its very easy.

Userlevel 1
Badge +10

Update: Writing to JSON worked, i.e. attributes where all values are missing were not written to the JSON file. However, this is not the desired output.

 

Have tried writing to Excel, csv, Esri geodatabase. Attributes where all values are missing were still present in the output, although they have no value (Excel, csv) or Null value (geodatabase).

 

A workaround could be writting to JSON first, then run another workbench to convert the data to Excel (desired output) but it would be great if all can be done in one run.

Ignore the attributes to exclude in the SchemaSetter, that only needs to be set if the attributes exist, if you are using python to remove the attributes they won't be included in the schema.

 

So the attribute might feature on the canvas

imageBut if it's missing it won't be used to create the schema in the schemasetterimage 

Reply