I use this script a lot.
Anyone know a way to add in EXIF info to the Comment before I write it out using
open(baseOut + os.sep + fileName, 'wb').write(binaryRep.tobytes())
I am also looking at adding it after the fact but figured this would be easier. Thanks
That did the trick! Can't believe I missed that!
Thank you!
Hi William Spiking ,
Just did a test with 10.3 and the code (stil) works. I do notice that in the name of the attachment table you have a single underscore:
'C:\PhotoLog\AGO\gdb\GPO_PhotoLog.gdb\Photo_Video_Documentation_ATTACH'
This should be a double underscore __ATTACH:
'C:\PhotoLog\AGO\gdb\GPO_PhotoLog.gdb\Photo_Video_Documentation__ATTACH'
Please try again with that little correction.
Hi Xander!
I know this thread is quite old, but I thought I'd give it a try anyway. I'm trying to implement your "QueryRelated Data" function in 10.3 and I'm getting the runtime errors below.
Runtime error
Traceback (most recent call last):
File "<string>", line 36, in <module>
File "<string>", line 17, in main
RuntimeError: cannot open 'C:\PhotoLog\AGO\gdb\GPO_PhotoLog.gdb\Photo_Video_Documentation_ATTACH'
Has anything changed with 10.3 that would cause these errors? I've provided my code as well. Any help would be greatly appreciated!
def main():
global arcpy
import arcpy, os
# fixed settings
fldBLOB = 'DATA'
fldAttName = 'ATT_NAME'
fldRelGID = 'REL_GLOBALID'
# your settings (edit these)
## related feature class
fc = r"C:\PhotoLog\AGO\gdb\GPO_PhotoLog.gdb\Photo_Video_Documentation"
## attachment table
tbl = r"C:\PhotoLog\AGO\gdb\GPO_PhotoLog.gdb\Photo_Video_Documentation_ATTACH"
fldRelatedInfo = 'CreationDate' # should be valid column in FC
with arcpy.da.SearchCursor(tbl,[fldBLOB,fldAttName,fldRelGID]) as cursor:
for row in cursor:
binaryRep = row[0]
fileName = row[1]
relGID = row[2]
# access related information
myRelatedInfo = QueryRelatedData(fc, fldRelatedInfo, relGID)
print myRelatedInfo
def QueryRelatedData(fc, fldRelatedInfo, relGID):
fldGID = 'GlobalID'
expression = arcpy.AddFieldDelimiters(fc, fldGID) + " = '{0}'".format(relGID)
with arcpy.da.SearchCursor(fc, (fldGID, fldRelatedInfo), where_clause=expression) as cursor:
return row[1]
break
del row
if __name__ == '__main__':
main()
Hi Xander,
Thanks for looking. We're running 10.0 right now, so it would be nice...but we're upgrading shortly to 10.2, so it's really not a big deal. No worries
Trill
Hi Trill,
I saw you code and gdb. Looks interesting. Just wondering... Do you really need the code in 10.0 or would running it on 10.2 be enough? What are the differences between the code that is running on 10.2 and the code that you included? What is the exact error that you receive when running the code on 10.0?
I don't have access to any 10.0 system anymore (do have 10.1, 10.2 and 10.3) so testing and tracing the error will be difficult.
Yeah, I've commented out the related info stuff for now since I don't need it just yet. Here's the code and geodb I'm working with. A bit more complex, since more than one feature class in the geodb has attachments, so I'm creating a dictionary for those. Also extracting attachments to separate folders per feature class. I have working code in 10.2, but not for 10.0. Thanks for taking a look!
I figured out the problem with the expression -- extra quotes are needed around the curly braces. Line 28 (or 35 in your snippet) should therefore read:
expression = arcpy.AddFieldDelimiters(fc, fldOID) + " = '{0}'".format(relOID)
Strange, in your code there is no reference to the OBJECTID field. Maybe due to the attachments it is trying to include it, but if the relationship is based on GlobalID, then there will be no OBJECTID (?).
The only thing I saw missing is the quote at the end of line 14 (but I think that is a copy error).
I'm working with this code sample in 10.2 to access related information from downloaded attachments. The first problem I'm running into is that my myFeatureClass_ATTACH has no REL_OBJECTID field, only a REL_GLOBALID field. When I adjust the code to use the expression to match the global id's instead of the object id's, I'm getting the following error:
I'm not sure why it's still trying to select OBJECTID, which is maybe the problem (?) -- anyway, see my modified code below. Please let me know if you have any ideas. Any guidance is much appreciated! Thanks -
def main(): global arcpy import arcpy, os # fixed settings fldBLOB = 'DATA' fldAttName = 'ATT_NAME' fldRelGID = 'REL_GLOBALID' # your settings (edit these) ## related feature class fc = r"C:\Forstmobil_2014.12.01\Geodaten\Forstmobil_2014.12.01.gdb\Baumkontrolle_AGS_online" ## attachment table tbl = r"C:\Forstmobil_2014.12.01\Geodaten\Forstmobil_2014.12.01.gdb\Baumkontrolle_AGS_online__ATTACH fldRelatedInfo = 'CreationDate' # should be valid column in FC with arcpy.da.SearchCursor(tbl,[fldBLOB,fldAttName,fldRelGID]) as cursor: for row in cursor: binaryRep = row[0] fileName = row[1] relGID = row[2] # access related information myRelatedInfo = QueryRelatedData(fc, fldRelatedInfo, relGID) print myRelatedInfo def QueryRelatedData(fc, fldRelatedInfo, relGID): fldGID = 'GlobalID' expression = arcpy.AddFieldDelimiters(fc, fldGID) + " = {0}".format(relGID) with arcpy.da.SearchCursor(fc, (fldGID, fldRelatedInfo), where_clause=expression) as cursor: for row in cursor: return row[1] break del row if __name__ == '__main__': main()
For anyone who is still looking for answers on extracting attachments from a secured ArcGIS online-hosted feature service: I've been working with Brian Brown (who has been helpful byond the call of duty) on developing a script that I can use to download attachments and replicate the entire hosted feature service locally.
Brian's base code can be found on his github site: https://github.com/bgeomapping/arcgis-toolboxes
I made some minor modifications to it, which are included in the attached code:
Other things to note: if the specified url ends in FeatureServer, the entire service will be replicated and all attachments for all layers with attachments in the service will be downloaded. If the specified url ends in FeatureServer/<layer index>, only that layer will be replicated and only attachments for that layer will be downloaded. Also, the code creates the following subdirectories for attachments: Layer > Feature OID > attachments, as well as an 'All attachments' folder -- I don't need the 'All attachments' portion, so it's commented out. This should work in both Python 2.6 and 2.7 (I've tested in 2.6, Brian in 2.7) and is written so that ArcGIS need not be installed on the machine running the script (in other words, no arcpy import).
I hope this helps some of you!!!
- Trill
Thanks a lot for taking the time to post this, I appreciate it!
Best regards
A code sample for 10.0 would be great, thank you. I'm also wondering if there's a way using 10.0 to access attachments from a service and extract them to a local disk. Everything I've found on this type of operation is for 10.1 an above.
Thanks again!
The functionality to extract the feature attachments is not limited to the da.cursor. The syntax will be different. The help provides some examples of how to use the cursor in 10.0:ArcGIS Desktop
If you have problems creating the proper syntax let me know and I will add the code sample for 10.0.
Kind regards, Xander
Hello,
I'm using 10.0, which as far as I know doesn't/can't use the arcpy.da module. How then would I go about extracting image attachments to disk without that module? Any feedback is greatly appreciated!
Would you be able to extend your code in python to be able to access images already stored as a BLOB field in SQL Server 2012 (non-GIS) as attachments without having to copy the images into ESRI feature classes thus eliminating data duplication of attachment files?
How would I go about added the relationship data into my python script."If you want to access the feature itself, you will have to use the "REL_OBJECTID" field from the attachment table and query the featureclass on OBJECTID = REL_OBJECTID..." I know you mentioned this way, but since it is a relationship does it need to be pathed to a geodatabase? Or how does it pull the relationship information with the pictures?
def main(): global arcpy import arcpy, os # fixed settings fldBLOB = 'DATA' fldAttName = 'ATT_NAME' fldRelOID = 'REL_OBJECTID' # your settings (edit these) fc = r"C:\Project\_LearnPython\Attachments\test.gdb\Meldingen" tbl = r"C:\Project\_LearnPython\Attachments\test.gdb\Meldingen__ATTACH" outFolder = r"C:\Project\_LearnPython\Attachments" fldRelatedInfo = 'SomeFieldInFeatureClass' # should be valid column in FC with arcpy.da.SearchCursor(tbl,[fldBLOB,fldAttName,fldRelOID]) as cursor: for row in cursor: binaryRep = row[0] fileName = row[1] relOID = row[2] # access related information myRelatedInfo = QueryRelatedData(fc, fldRelatedInfo, relOID) # do something with the related info # save attachment to disk open(outFolder + os.sep + fileName, 'wb').write(binaryRep.tobytes()) del row del binaryRep del fileName def QueryRelatedData(fc, fldRelatedInfo, relOID): fldOID = 'OBJECTID' expression = arcpy.AddFieldDelimiters(fc, fldOID) + " = {0}".format(relOID) with arcpy.da.SearchCursor(fc, (fldOID, fldRelatedInfo), where_clause=expression) as cursor: for row in cursor: return row[1] break del row if __name__ == '__main__': main()
Hi Xander,Thanks for your response.Actually I was looking about "Feature Attachments", which involves a relationship table to store the attachments for features.Please go through "Query attachments" section in below link, which talks about performing the same task in .Net.http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//0001000001qr000000
from arcpy import da import os # fc = r"C:\Project\_LearnPython\Attachments\test.gdb\yourFCname" tbl = r"C:\Project\_LearnPython\Attachments\test.gdb\yourFCname__ATTACH" fldBLOB = 'DATA' fldAttName = 'ATT_NAME' outFolder = r"C:\Project\_LearnPython\Attachments" with da.SearchCursor(tbl,[fldBLOB,fldAttName]) as cursor: for row in cursor: binaryRep = row[0] fileName = row[1] # save to disk open(outFolder + os.sep + fileName, 'wb').write(binaryRep.tobytes()) del row del binaryRep del fileName
"Feature attachments" is the new feature from ArcGIS 10 on wards. How to extract feature attachments and save to disk using Python?
from arcpy import da import os with da.SearchCursor(r"c:\temp\demo.gdb\table",['blobFieldname','fileName']) as cursor: for row in cursor: binaryRep = row[0] fileName = row[1] # save to disk open(r"c:\saveFolder" + os.sep + fileName, 'wb').write(binaryRep.tobytes()) del row del binaryRep del fileName
Angemeldete Mitglieder können Beiträge verfassen, Updates folgen und mehr. Neu hier? Registriere ein kostenloses Konto.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.