I have a feature class that has several attachments stored in related tables. I've been trying to use this Export Attachments script to store the attachments in a local folder, but things aren't working right.
import arcpy from arcpy import da import os inTable = 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 tool runs successfully with no errors or warnings. My output location remains empty though. I was thinking that it might just be an indexing issue. This is my attachment table.
I've ran the script as is, and I've also ran it by indexing "filenum" to [0] and "filename" to [4], the ATT_NAME field. I've verified that there are actually attachments in the related table. Does anyone know what I could be doing wrong here? Thanks.
EDIT: I just realized that the input and output just indices to the inputs in the tool. Here's what the tool looks like. Running a script like above without putting anything into the tool won't work...unless I hardcode the parameters (having trouble with that too!).
Seems to be working just fine for me as is.
Might be something to do with your path/locations. You could try hard coding the paths and see if that resolves the issue. Then, at least you know where it is going wrong.
Also, make sure you are pointing the search cursor at the attachment table and not the feature class.
fileLocation = r'C:\tmp\Attachments' # folder where attachments are saved
inTable = r'Database Connections\SignsDatabase.sde\SignsDatabase.DBO.Signs__ATTACH' # attachment table for feature class
Also, can't see the full ATT_NAME in your table, but looks like it could be long with multiple characters.
Want to make sure the final path/filename are still valid filenames within windows.
R_
I've hard coded the paths in there with raw string file paths, and now I'm getting a runtime error saying that it can't open my attachment table.
Traceback (most recent call last):
File "C:/Users/UserName/Documents/Projects/Scripts/ExportAttachments.py", line 11, in <module>
with da.SearchCursor(inTable, ['DATA', 'ATT_NAME', 'ATTACHMENTID']) as cursor:
RuntimeError: cannot open 'C:\Users\UserName\Documents\Projects\MI Green Schools Export\5b060c49-050b-40fa-938b-542ca0ec171b.gdb'
Does your ATT_NAME include the file extension at the end?
Yeah, all the ATT_NAMEs have extensions at the end. There is one attachment table that's empty, but I haven't been able to get the code to extract the files even on the tables that actually have attachments.
If you put some print statements in there, what is is saying for:
print inTable
print fileLocation + os.sep + filename
R_
Printing the inTable points to the .gdb of the attachment table. I can't print the filename because it's nested within the for loop and the code needs to access the attachment table in order for the filename to be generated.
I only see that error when inTable is set to the FGDB and not to the attachment table itself.
Does adding the path to the actual attachment table make a difference?
print inTable right before the cursor would show you what it is actually using.
inTable = r'C:\Users\UserName\Documents\Projects\MI Green Schools Export\5b060c49-050b-40fa-938b-542ca0ec171b.gdb\tablename__ATTACH'
Don't think it would make a difference with anything here put the print statements, but are you running python 2.7 or 3.x?
R_
Python 2 or 3?
Sounds like all you need to do is update inTable to point to the actually attachments table (Not the .gdb) and should be good to go.
import arcpy
from arcpy import da
import os
inTable = arcpy.GetParameterAsText(0)
fileLocation = arcpy.GetParameterAsText(1)
print inTable # for python 2.7
print(inTable) # for python 3
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])
print fileLocation + os.sep + filename # python 2.7
print(fileLocation + os.sep + filename) # python 3
open(fileLocation + os.sep + filename, 'wb').write(attachment.tobytes())
del item
del filenum
del filename
del attachment
If not, you can add print statements to the code as above. This will have access to the variable within the loop.
R_