Skip to main content

Hi, I would like to use PythonCaller to generate a new attribute, but I don't know what the attribute name will be until it is set within the Python Script.

How can I expose an attribute in the PythonCaller without knowing its name in advance?

I am using FME2016 Desktop.

Thanks,

Will you use attribute values or parameters to construct this attribute name? Or where will the name come from exactly?

 

 

What might help you is the method 'getAllAttributeNames'. This will create a list that contains all attributes of each feature. With a for loop and the 'setAttribute' method, you can dynamically expose all attributes. Off course, I know you wanted to expose only 1 attribute, but this might get you going...


You can't expose attributes dynamically with the PythonCaller. You can create them, but you manually need to expose them using the Expose Attributes field of the PythonCaller transformer. Which is not dynamic at all, of course.

However, there are other ways to work with dynamic attributes and Python can be used to create a list of attributes that you wish to expose. This is demonstrated in this thread, for instance.


Hi, thank you for your answers.

I realised I wrote my question very misleadingly. I actually do know the names of the attributes I want to expose, but I didn't know how to use them in the 'feature.setAttribute()' python method because the name of the attribute is set by a variable value rather than a variable name.

However I found a way to do it by setting the variable value as a 'key' in the key/value pair in Python dictionaries:

for key, value in col_names.items():

key1 = key

 

value1 = value

 

feature.setAttribute(key1, value1)

 


Hi, thank you for your answers.

I realised I wrote my question very misleadingly. I actually do know the names of the attributes I want to expose, but I didn't know how to use them in the 'feature.setAttribute()' python method because the name of the attribute is set by a variable value rather than a variable name.

However I found a way to do it by setting the variable value as a 'key' in the key/value pair in Python dictionaries:

for key, value in col_names.items():

key1 = key

 

value1 = value

 

feature.setAttribute(key1, value1)

 

Ah alright, yes that's a different question 🙂

 

But glad you figured it out. Be aware though, that your method might raise errors if you're using Python 2.* and the key is a Unicode object instead of a regular string, which setAttribute() expects.

 

Oh and you don't need to reassign key and value to key1 and value1. You can use both values immediately in the function call.

 

 


Ah alright, yes that's a different question 🙂

 

But glad you figured it out. Be aware though, that your method might raise errors if you're using Python 2.* and the key is a Unicode object instead of a regular string, which setAttribute() expects.

 

Oh and you don't need to reassign key and value to key1 and value1. You can use both values immediately in the function call.

 

 

Thank you for the warning 🙂 I haven't noticed any errors so it must be a regular string. But I'll bear that in mind for future!

 

 


Actually there is a way to dynamically expose attributes within the PythonCreator or Caller, BUT it involves
reading itself and you should be very carefull doing this:

import fmeobjects, os
my_set = set()
for feature in whatever_containing_features: # Change this part to loop through your atr
for attribute in feature:
my_set.add(attribute)
iAm = os.path.join(FME_MacroValuesu'FME_MF_DIR_DOS'],FME_MacroValues_'FME_MF_NAME'])
iWillBe = iAm.replace('.fmw','')+'_copy.fmw' # creates a new model with 'same name'_copy.fmw
line_phrase = '#!     <XFORM_PARM PARM_NAME="NEW_ATTRIBUTES" PARM_VALUE="showAll' #expose showAll in your python transformer
with open(iAm, 'r') as f:
    with open(iWillBe,'w') as output: 
        for line in f.readlines():
            if line.startswith(line_phrase):
                output.write(line.replace('showAll',' '.join(my_set)))
            else:
                output.write(line)
    output.close()
f.close()

notice PARM_VALUE="showAll

what you need to do is expose the value "showAll" (it doesn't need to say showAll, whatever unique name inside the fme model will do, but then change the line_phrase to match your line phrase) in the python transformer then run this script, of course modify the part: for feature in whatever_containing_features, for you to loop through all the attributes you want to show.

This script then makes a new fmw file with the samename_copy.fmw 

Run it only once, then you can continue your project on the new fmw model.


Reply