Skip to content

Instantly share code, notes, and snippets.

@AlexArcPy
Last active August 29, 2023 04:22
Show Gist options
  • Select an option

  • Save AlexArcPy/c4553218fa69c3623282d9ad445bc33e to your computer and use it in GitHub Desktop.

Select an option

Save AlexArcPy/c4553218fa69c3623282d9ad445bc33e to your computer and use it in GitHub Desktop.
ArcPy: Batch export of attachments from geodatabase feature class with custom naming
'''This code will export the attachments associated with a feature class features into
a folder naming output files using the feature's attribute provided'''
import arcpy
import os
##define input parameters for the tool
#input attachments table
in_table = arcpy.GetParameterAsText(0)
#output folder to save files in
file_location = arcpy.GetParameterAsText(1)
#field to be used for naming attachments
name_field = arcpy.GetParameterAsText(2)
#getting the feature class name from the attachments table through the relationship class
#simple way to do this - however might break should the table be named in another way in
#upcoming releases - is to use `in_table.split('__')[0]`
in_table_desc = arcpy.Describe(in_table)
relclass = os.path.join(in_table_desc.path, in_table_desc.relationshipClassNames[0])
rel_class_desc = arcpy.Describe(relclass)
fc = os.path.join(rel_class_desc.path, rel_class_desc.originClassNames[0])
foreign_key_field = [i[0] for i in rel_class_desc.originClassKeys if i[1] == 'OriginForeign'][0]
##creating a dict with values to be used for naming output attachments files
globalid_field = arcpy.Describe(in_table).globalIDFieldName
with arcpy.da.SearchCursor(fc, [globalid_field, name_field]) as lookup:
feature_names = {row[0]: row[1] for row in lookup}
##iterating attachments and saving them on disk
with arcpy.da.SearchCursor(in_table, [foreign_key_field, 'DATA', 'Content_Type']) as cursor:
for item in cursor:
featureid = item[0]
attachment = item[1]
featurename = feature_names[featureid]
if not isinstance(featurename, unicode):
featurename = str(featurename)
filename = featurename + '.' + item[2].split('/')[1]
#constructing the output file path
filepath = os.path.join(file_location,filename)
with open(filepath, 'wb') as f:
f.write(attachment.tobytes())
@swfbtucs

Copy link
Copy Markdown

Just realized unicode has been replaced by str. So now that line works.

@BlueTalon6

Copy link
Copy Markdown

Handy script. One problem though, line 24 gets the globalIDFieldName from the attach table, should be from the related fc. GUID values from this field are used to create keys for the feature_names dict, but then the foreign_key_field values are used as a lookup to this dict.
This works if default names were used, but if the related table has a non-default named globalid field, e.g. globalid_1, then it will fail.
Line 24 should be:
globalid_field = arcpy.Describe(fc).globalIDFieldName

@BlueTalon6

Copy link
Copy Markdown

@swfbtucs if there's only one feature, you're using the same value from name_field to name your output and therefore it is getting overwritten with each export. You need to append a unique value to the name for each attachment (can use OID from the related fc).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment