In the code below, line 14, 'alias = dict[fld.name]', always throws an exception. I don't see why; printing out fld.name works just fine. Also, the exception message is the field name printing correctly.
Printing the dictionary keys and values also works fine. The ultimate goal is to get a string to set as the field alias using AlterField. Thanks.
with arcpy.da.SearchCursor(metatable, metaflds) as rows: for row in rows: if not moe in row[1]: fn = row[1].replace(' ', '') fn = fn.replace(est, '') dict[row[0]] = fn # Get list of tables to add alias to tbls = arcpy.ListTables() for tbl in tbls: tblflds = arcpy.ListFields(tbl) for fld in tblflds: try: alias = dict[fld.name] # exception raised here print(alias) except Exception as e: import traceback import sys tb = sys.exc_info()[2] print('Oh no!') print("Line {0}".format(tb.tb_lineno)) print(e.message)
Solved! Go to Solution.
Yes, that's what it would mean, except I can see it's there. Printing the keys and values prints the correct sequences.
Anyway, I got it to work by changing alias = dictflds[fld.name] to alias = dictflds.get(fld.name, 'None'). No idea why the first method didn't work if the second does, but I've spent enough time on this. Thanks for the help, appreciate it.
A few things. What is the error message, specifically? Second, it seems you are naming your dictionary 'dict', which shadows the built-in dict constructor. Although shadowing a built-in doesn't break the code, per se, it does make it more difficult to read and therefore more prone to errors. Third, the code snippet doesn't show the dictionary object being created, is that just handled earlier?
Thanks Joshua. I changed the name of the dictionary to dictflds. The error I get if I try to access the value outside of the try block is KeyError: u'B01001e1', and the error when in the try block reads Line 45, B01001e1, where the line number is wherever I first try to access the dictionary value and B01001e1 is a valid field name. It's not that particular value that's a problem; the error occurs for every field. I've tried enclosing it in str(), setting it to a variable both when accessing it and setting the key, no luck. If I just print fld.name, works fine. Full code (minus header comments) below.
import arcpy, os from arcpy import env env.workspace = r'K:\Projects\Other Depts\Planning\Lori_Census\Census.gdb' def main(): metatable = 'BG_Metadata_2012' metaflds = ('Short_Name', 'Full_Name') est = '--(Estimate)' moe = 'Margin of Error' dictflds = {} # Get dictionary of short names and corresponding full names from metadata # table, skipping moe fields and removing whitespace and estimate text from # full name. with arcpy.da.SearchCursor(metatable, metaflds) as rows: for row in rows: if not moe in row[1]: fn = row[1].replace(' ', '') fn = fn.replace(est, '') dictflds[row[1]] = fn for k, v in dictflds.iteritems() print(' : '.join([k, v]) # works fine # Get list of tables to add alias to tbls = arcpy.ListTables() for tbl in tbls: tblflds = arcpy.ListFields(tbl) for fld in tblflds: try: print(fld.name) # works fine alias = dictflds[fld.name] # exception raised here print(alias) print(' : '.join[tbl, fld.name, alias]) arcpy.AlterField_management(tbl, fld, new_field_alias=alias) except Exception as e: import traceback import sys tb = sys.exc_info()[2] print('Oh no!') print("Line {0}".format(tb.tb_lineno)) print(e.message) # this prints the fld.name value if __name__ == '__main__': main()
The Key Error outside of the Try block is the crux of the issue. As far as the interpreter is concerned, there is no key corresponding to the value you are giving it, so it returns a Key Error, i.e., u'B01001e1' is not key, period. At this point, are there any differences in capitalization or white spaces? I don't think it is an text encoding issue. Trying printing your dictionary (print dictflds) and double checking that there is in fact a u'B01001e1' key.
Yes, that's what it would mean, except I can see it's there. Printing the keys and values prints the correct sequences.
Anyway, I got it to work by changing alias = dictflds[fld.name] to alias = dictflds.get(fld.name, 'None'). No idea why the first method didn't work if the second does, but I've spent enough time on this. Thanks for the help, appreciate it.