Converting an Arcade expression into Python

1783
5
12-31-2020 12:49 PM
JasonBennett
New Contributor II

Currently, I use the following Arcade expression on a field calculation to count the number of attachments a feature has and set that number in the field.

return Count(Attachments($feature))

 

Is there a simple way to do the same thing in Python? I just want to get a count of the attachments.

5 Replies
Robert_LeClair
Esri Notable Contributor

Jason - Example 2 in this link would do the same thing in Python I believe.  Word of warning, I am not a Python expert by any means though!  Good luck!

XanderBakker
Esri Esteemed Contributor

Hi @JasonBennett ,

To count the attachments, would require more line, since you would have to go from the feature to the related table with the attachments and query the attachments before you can do the count.

 

Are you trying to update an attribute on the layer to indicate the number of attachments per feature? Is the data static? If not, you will have to recalculate the values when the features and attachments are updated-

JasonBennett
New Contributor II

Thanks for the info. I am trying to update an attribute with the total number of attachments per feature. The data is not static. In my current solution, I already have to periodically run the calculation.

It sounds like Python may not be worth the trouble here, especially since I have a working solution. I want Python to become a common part of my workflow in ArcGIS Pro and thought converting this would be good practice.

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Not sure if you are using or talking about Field Calculator.  If so, the short answer to your question is, "no."  There is no way using Python with the Field Calculator to emulate the Arcade code for counting attachments.  Outside of Field Calculator, the answer to your question is, "not really."  That is, the ArcPy way of updating a field to reflect the attachment count isn't what most people would consider 'simple,' although it is quite possible.

The following code snippet should work:

 

import arcpy
import os
import warnings
from collections import defaultdict

table = # path to table
attach_count_field = # field for holding count of attachments

dcn = []
desc = arcpy.Describe(table)
for name in desc.relationshipClassNames:
    rel = arcpy.Describe(os.path.join(desc.path, name))
    if rel.isAttachmentRelationship:
        dcn = rel.destinationClassNames

if not dcn:
    warnings.warn("Table '{}' does not have attachments enabled".format(table))

attach_count = defaultdict(int)
for name in dcn:
    with arcpy.da.SearchCursor(os.path.join(desc.path, name), "REL_OBJECTID") as cur:
        for rel_oid, in cur:
            attach_count[rel_oid] += 1

with arcpy.da.UpdateCursor(table, ["OID@", attach_count_field]) as cur:
    for oid, _ in cur:
        cur.updateRow([oid, attach_count[oid] if dcn else None])

 

If a table had attachments and they were removed/disabled, the code will set the count field to NULL to reflect attachments are not enabled.

JasonBennett
New Contributor II

Thank you for the code snippet. I thought I would have more time to look into this this week but I will take a look at your solution in the future.

0 Kudos