I am completing a task that requires me to collect info and pictures of gravestones in cemeteries using the Esri Collector app. There are thousands of attachments within the GDB that I would like to be renamed to show the unique section number and also the actual headstone number and the global ID.

So for example it would show [(section#) - (Headstone#) (GlobalID)] 1-1 {9E0682F9-36F6-490C-8CDE-57E3E9BCCF33}. I am quite the novice when it comes to Python.

The obviously wrong script that I have been using is:

import arcpy
from arcpy import da
import os

inTable = arcpy.GetParameterAsText(0)
fileLocation = arcpy.GetParameterAsText(1)

with da.SearchCursor(inTable, ['DATA', 'ATT_NAME', 'ATTACHMENTID', 'GLOBALID']) as cursor:
    for item in cursor:
        attachment = item[0]
        filenum = "ATT" + str(item[2]) + "_"
        filename = 'GLOBALID' + filenum + str(item[1])
        open(fileLocation + os.sep + filename, 'wb').write(attachment.tobytes())
        del item
        del filenum
        del filename
        del attachment

Esri support said to put print statements in the code after (item1) and (item2) but I'm not sure what to put in those actual statements. Attached is what was made when I ran the script. I can tell that the script just put globalID in the name and not the actual global ID.

Also attached is the table in AGOL.

  • I assume your points have this information in their table? – FelixIP Nov 8 '19 at 5:26

I have used the code below to rename attachments captured using the Collector App. I used this as an answer here:

Exporting photos from Survey123 GDB file with custom filenames?

I cannot take credit for the code, it is a mix of things I have found on this site and Google searches. You will need to change it to match the names of the fields you are working with.

def execute(self, parameters, messages): origTable = parameters[0].ValueAsText #Input Featureclass attachTable = parameter

s[1].ValueAsText # if no attachTable given, append __ATTACH to origTable
       nameField = parameters[3].ValueAsText  # appropriate name field in origTable
       fileLocation = parameters[2].ValueAsText #Output Folder

       origFieldsList = ["GlobalID", "OBJECTID", nameField] # GlobalID for linking, OBJECTID for renaming, nameField for renaming

    # Use list comprehension to build a dictionary from a da SearchCursor
       valueDict = {r[0]:(r[1:]) for r in arcpy.da.SearchCursor(origTable, origFieldsList)}

       count = 1
       with arcpy.da.SearchCursor(attachTable, ['DATA', 'ATT_NAME', 'ATTACHMENTID', 'REL_GLOBALID']) as cursor:
        for item in cursor:
            attachment = item[0] # attachment data

            filenum = "ATT" + str(item[2]) + "_"

            filename = filenum + str(item[1])  # this will be the filename if linking fails

        # store the Join value of the row being updated in a keyValue variable
            keyValue = item[3] # REL_GLOBALID
        # verify that the keyValue is in the Dictionary
            if keyValue in valueDict:
            # transfer the values stored under the keyValue from the dictionary to the updated fields.
                obID = valueDict[keyValue][0]

            # remove invalid filename characters, replace spaces and periods, limit length
                check = str(valueDict[keyValue][1])

                if check == 'None':  #Check for Null Values
                    namefield = "NoValue"
                    namefield = re.sub('[^0-9a-zA-Z]+', '_', valueDict[keyValue][1])[:18]

            # Create a unique filename  ObjectID_AttachmentID_namefield.ext
                ext = filename.rsplit('.', 1)[-1] # keep extension of original file
                filename = "{}_{}_{}.{}".format(namefield,"OID" + str(obID),"ATTID" +str(item[2]),ext)

            arcpy.AddMessage( "Writing: {}{}{}".format(fileLocation, os.sep, filename))
            arcpy.AddMessage ("Processing: " + str(count))
            count = count +1

            open(fileLocation + os.sep + filename, 'wb').write(attachment.tobytes())
            del item
            del filenum
            del filename
            del attachment
        del count

There are 4 parameters, in order they are: 1. origTable - the input feature class - the point feature from your survey 2. AttachTable - This is the table containing the attachments, it is usually the original table name with "__ATTACH" on the end. 3. nameField - appropriate name field in origTable - the name you want to add to the attachment exported 4. fileLocation - a folder path

You will need to code these into your script. The script then looks over the REL_GLOBAL ID in the Attachment Table and finds the appropriate GLOBAL ID in the main table and looks for the field you specified as an input, and then assigns that name to the attachment name. If there are more than one attachments per point, it adds a number to the end.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.