I have a Python Toolbox (.pyt) containing a single tool. Part of that tool is the following function, which creates a dictionary from an attribute table, where the keys are the rows' OBJECTIDs and the values are pulled from a field specified when calling the function. The attributes are accessed with a generator based on an arcpy.da.SearchCursor
.
def make_oid_dict(fc, value_field):
describe = arcpy.Describe(fc)
key_field = describe.OIDFieldName
key_value_pairs = (row for row in arcpy.da.SearchCursor(fc, (key_field, value_field)))
oid_dict = dict(key_value_pairs)
return oid_dict
I want to use the dictionary to access attribute values of the feature IDs in a Near Table. I've been trying to run the tool, but every time it calls this function -- for a point feature class with about 1.25 million rows and a value_field
that is formatted as a Long integer -- it fails with a Python MemoryError
.
I have successfully called the function on the same feature class from the Python window in ArcCatalog, so I have no idea why it wouldn't be working from within the Python toolbox. The resultant dictionary isn't even that large: just 24 MB, according to sys.getsizeof()
.
Any ideas what the problem might be?
Edit 1: I've updated the function to use a dictionary comprehension as follows, per Jason Scheirer's suggestion, but that unfortunately has not solved the MemoryError
issue.
def make_oid_dict(fc, value_field):
describe = arcpy.Describe(fc)
key_field = describe.OIDFieldName
oid_dict = {row[0]: row[1] for row in arcpy.da.SearchCursor(fc, (key_field, value_field))}
return oid_dict
Edit 2: This is an update to clarify the solution(s).
My make_oid_dict()
function works for me without throwing a MemoryError
if and only if the tool is run using background processing (i.e. by setting self.canRunInBackground = True
in the tool's __init__
method). Thanks to Aaron for pointing me in this direction.
In the case that the tool needs to run in foreground processing mode, however, Jason Scheirer's make_oid_array()
function will run successfully -- or at least it did for me.
MemoryError
has miraculously vanished. WTF, Esri?