Hello,
I am able to export photo attachments with the generic script but I would like to name them based on a field on the record they are attached to. The field I would like to use is 'FID' and it's unique to each row in the table. The current code I use is.
import arcpy
from arcpy import da
import osinTable = arcpy.GetParameterAsText(0)
fileLocation = arcpy.GetParameterAsText(1)with da.SearchCursor(inTable, ['DATA', 'ATT_NAME', 'Access Point FQN_ID']) as cursor:
for item in cursor:
attachment = item[0]
filenum = "ATT" + str(item[2]) + "_"
filename = filenum + str(item[1])
open(fileLocation + os.sep + filename, 'wb').write(attachment.tobytes())
del item
del filenum
del filename
del attachment
Solved! Go to Solution.
This will get filename information from the master feature class and save an attachment in a related table.
import arcpy
masterFC = r"C:\Path\to\file.gdb\masterFC"
masterFlds = ['GlobalID', 'Name']
# Use list comprehension to build a dictionary from a da SearchCursor
masterDict = {r[0]:(r[1:]) for r in arcpy.da.SearchCursor(masterFC, masterFlds)}
print masterDict
relatedTbl = r'C:\Path\to\file.gdb\related_ATTACH'
relatedFlds = ['REL_GLOBALID', 'ATT_NAME', 'DATA']
fileLocation = r'C:\Path\to\attachments'
with arcpy.da.SearchCursor(relatedTbl, relatedFlds) as cursor:
for item in cursor:
# item[0] is related GlobalID; take first item in masterDict tuple with that key
f1 = masterDict[item[0]][0].replace(" ","_") # replacing spaces
# assuming attachment name starts with "attachment", remove that part and keep rest
f2 = item[1][10:] # can use .split('.')[1:] or similar to get just extension
# make new filename
filename = "ATT_{}_{}".format(f1, f2)
print filename
open(fileLocation + os.sep + filename, 'wb').write(item[2].tobytes())
del cursor
This assumes that the master feature class contains some attributes like:
And the related attachments table is something like:
The dictionary and filenames created are:
# print masterDict
{u'{B0174984-E7EB-47EA-A49A-9D535CFD6125}': (u'State Office Building',), u'{43902175-71ED-47DB-BCC8-6C805D930D23}': (u'State Capitol',)}
# print filename
ATT_State_Capitol_1.jpg
ATT_State_Capitol_2.jpg
ATT_State_Office_Building_1.jpg
Hope this helps.
/blogs/dan_patterson/2016/08/14/script-formatting would help make sure there aren't any formatting errors Craig.
Also, I don't see where you added the FID field into the searchcursor. You will need that for your id numbers.
I presume that you haven't tested this yet?
import arcpy
from arcpy import da
import osinTable = arcpy.GetParameterAsText(0)
fileLocation = arcpy.GetParameterAsText(1)with da.SearchCursor(inTable, ['DATA', 'ATT_NAME', 'ATTACHMENTID']) as cursor:
for item in cursor:
attachment = item[0]
filenum = "ATT" + str(item[2]) + "_"
filename = filenum + str(item[1])
open(fileLocation + os.sep + filename, 'wb').write(attachment.tobytes())
del item
del filenum
del filename
del attachment
The code is what I used. I posted the wrong code earlier.
I don't know if I explained what I was trying to say earlier. I need a way to save the images and have the filename be the ID of the record they are attached to or have the filename include a field from the record they are attached too. I will give an example.
Record in table is {D40A7E01-4D12-453C-A69E-BEB4E59D9A2C}. The ID in the attachment table is df6ea7eb9fb3464f9313cae304c2b27d.
Is this possible to do this or export the relationship table?
The record for the attachment should contain the global ID of the linked/master record in one of the fields. As shown my example code, you can work it into the file name. If the master record can have multiple attachments, you will need to use some sort of count, perhaps the attachment ID, to make a unique filename. You will want to append a file extension which could be obtained from splitting the filename at the dot in your code or by using the data in the content type field to create an extension.
If you want to create a filename using data from the master record other than the global/linking ID field, you should be able to do that by using some sort of join with the master table or creating a dictionary of the master record feature/table.
I will work on a code sample later today or this weekend that illustrates this.
I really didn't find any major problems with your script. For testing, my script was similar:
import arcpy, os
inTable = r'C:\Path\to\file.gdb\feature__ATTACH'
fileLocation = r'C:\Path\to\attachments'
with arcpy.da.SearchCursor(inTable, ['DATA', 'ATT_NAME', 'ATTACHMENTID']) as cursor:
for item in cursor:
print "ATT_NAME: {} - ATTACHMENTID: {}".format(item[1], item[2])
filename = "ATT_{}_{}".format(item[2], item[1])
print filename
open(fileLocation + os.sep + filename, 'wb').write(item[0].tobytes())
del cursor
I would suggest testing with some print statements (or AddMessage), to see that your input table and file location strings are being interpreted correctly. For the filename, you might want to start with the attachment ID as the ATT_NAME field may include a file extension. If it does not contain an extension, you may need to look at the CONTENT_TYPE field so your code can append one if necessary.
This will get filename information from the master feature class and save an attachment in a related table.
import arcpy
masterFC = r"C:\Path\to\file.gdb\masterFC"
masterFlds = ['GlobalID', 'Name']
# Use list comprehension to build a dictionary from a da SearchCursor
masterDict = {r[0]:(r[1:]) for r in arcpy.da.SearchCursor(masterFC, masterFlds)}
print masterDict
relatedTbl = r'C:\Path\to\file.gdb\related_ATTACH'
relatedFlds = ['REL_GLOBALID', 'ATT_NAME', 'DATA']
fileLocation = r'C:\Path\to\attachments'
with arcpy.da.SearchCursor(relatedTbl, relatedFlds) as cursor:
for item in cursor:
# item[0] is related GlobalID; take first item in masterDict tuple with that key
f1 = masterDict[item[0]][0].replace(" ","_") # replacing spaces
# assuming attachment name starts with "attachment", remove that part and keep rest
f2 = item[1][10:] # can use .split('.')[1:] or similar to get just extension
# make new filename
filename = "ATT_{}_{}".format(f1, f2)
print filename
open(fileLocation + os.sep + filename, 'wb').write(item[2].tobytes())
del cursor
This assumes that the master feature class contains some attributes like:
And the related attachments table is something like:
The dictionary and filenames created are:
# print masterDict
{u'{B0174984-E7EB-47EA-A49A-9D535CFD6125}': (u'State Office Building',), u'{43902175-71ED-47DB-BCC8-6C805D930D23}': (u'State Capitol',)}
# print filename
ATT_State_Capitol_1.jpg
ATT_State_Capitol_2.jpg
ATT_State_Office_Building_1.jpg
Hope this helps.
Thanks Randy! That is exactly what I needed!
So I've been following these instructions. This is my code:
----------------------------------------------------------------------------------------------------------
import arcpy
masterFC = r"C:\Users\kameehan\OneDrive - Westwood Active Directory\Documents\Project_Documents\UI_Railroad\Shapefiles\Observations_FGDB\UI_Walkdown_Observations.gdb\Observations"
masterFlds = ['GlobalID', 'NAME']
# Use list comprehension to build a dictionary from a da SearchCursor
masterDict = {r[0]:(r[1:]) for r in arcpy.da.SearchCursor(masterFC, masterFlds)}
print(masterDict)
relatedTbl = r'C:\Users\kameehan\OneDrive - Westwood Active Directory\Documents\Project_Documents\UI_Railroad\Shapefiles\Observations_FGDB\UI_Walkdown_Observations.gdb\Observations_ATTACH'
relatedFlds = ['REL_GLOBALID', 'ATT_NAME', 'DATA']
fileLocation = r'C:\Users\kameehan\OneDrive - Westwood Active Directory\Documents\Project_Documents\UI_Railroad\Shapefiles\Observations_FGDB\UI_Walkdown_Observations.gdb\Observations_ATTACH'
with arcpy.da.SearchCursor(relatedTbl, relatedFlds) as cursor:
for item in cursor:
# item[0] is related GlobalID; take first item in masterDict tuple with that key
f1 = masterDict[item[0]][0].replace(" ","_") # replacing spaces
# assuming attachment name starts with "attachment", remove that part and keep rest
f2 = item[1][10:] # can use .split('.')[1:] or similar to get just extension
# make new filename
filename = "ATT_{}_{}".format(f1, f2)
print (filename)
open(fileLocation + os.sep + filename, 'wb').write(item[2].tobytes())
del cursor
---------------------------------------------------------------------------------------------------------------------------
and I keep getting this error:
Traceback (most recent call last): File "C:\Users\kameehan\OneDrive - Westwood Active Directory\Documents\ExportAttachments2.py", line 16, in <module> with arcpy.da.SearchCursor(relatedTbl, relatedFlds) as cursor: RuntimeError: cannot open 'C:\Users\kameehan\OneDrive - Westwood Active Directory\Documents\Project_Documents\UI_Railroad\Shapefiles\Observations_FGDB\UI_Walkdown_Observations.gdb\Observations_ATTACH'
Failed to execute (ExportAttachments2).
And I'm not sure how to fix it or what is wrong. As in why won't it open that file path?
rvburton Please let me know if you have any clue, or might need more information to potentially help, if you could!