Iterate an annotation feature class in arcpy

Discussion created by drunix on Jul 11, 2018
Latest reply on Jul 11, 2018 by mvolz47

I finally figured out how to iterate an annotation feature class in arcpy to update its attributes.

You cannot use a cursor , it just generates errors. You cannot directly use SQL and bypass arcpy because the attribute columns are just for show, the real data is hidden in a binary column you can't see in ArcGIS.


But you can use CalculateField_management.


Roughly put,

codeblock = """def writekv(k, v)

  # do some calculation here, put it in "newvalue'
  return newvalue

expression = "writekv(!%s!, !%s!)" % (keyfield, valuefield)

arcpy.CalculateField_management(layer, fieldname, expression, "PYTHON_9.3", codeblock)

where keyfield and valuefield are the names of attribute fields you want to use

and fieldname is the name of the attribute being calculated.


All the normal python rules apply of course - indentation and you can use "import" and so on. I have been writing functions in the main body of my python script so that I can write unit tests, get the calculations correct, before getting into wrapping the code in a "codeblock" string. In this case the code looks something like this


#big long lookup table here

lut = { 1:"fine", 2:"dandy" }

def myfunc(x):

  # do some long python thing here

  y = lut[x] # use a lookup table you've carefully tested in advance

  return y


codeblock="""from thisfile import myfunc

def f(x):

  return myfunc(x)"""


arcpy.CalculateField_management(layer, "SomeTextField", "f(!INTEGERFIELD!)", "PYTHON_9.3", codeblock)

This puts just the minimum needed inside "codeblock" (making it all much easier to debug) and in my example runs a function called myfunc that you can test separately.

This assumes all your code is in a file called "thisfile.py". In "codeblock" it does an import, that is so that the copy of python running in the field calculator can use a lookup table called lut that's declared outside the function "myfunc".


I have to adjust the font sizes in 300,000+ records and this is working for me.