Extract Feature Attachments

19714
32
10-24-2013 01:13 AM
Ranga_Tolapi
Occasional Contributor III
"Feature attachments" is the new feature from ArcGIS 10 on wards. How to extract feature attachments and save to disk using Python?
Tags (2)
0 Kudos
32 Replies
TrilliumLevine1
Occasional Contributor

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!

0 Kudos
XanderBakker
Esri Esteemed Contributor

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

0 Kudos
TrilliumLevine1
Occasional Contributor

Hi Xander,

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!

0 Kudos
XanderBakker
Esri Esteemed Contributor

Observe code sample below. Once again I haven't tested the code, so be careful.

Changes in syntax can be found on lines 16, 18-20 + 35 and 37

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.SearchCursor(tbl) as cursor:

        for row in cursor:

            binaryRep = row.getValue(fldBLOB)

            fileName = row.getValue(fldAttName)

            relOID = row.getValue(fldRelOID)

            # 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.SearchCursor(fc, where_clause=expression) as cursor:

        for row in cursor:

            return row.getValue(fldRelatedInfo)

            break

        del row

if __name__ == '__main__':

    main()

0 Kudos
TrilliumLevine1
Occasional Contributor

Hi Xander,

I just tested this code (right now just for extracting attachments with 10.0, not accessing the related info) and I had to change line 16 to:

cursor = arcpy.SearchCursor(tbl)

I'm also getting an error from line 27 -- interestingly this isn't a problem in 10.2, but it's kicking up dust in 10.0.  Error is: AttributeError: 'NoneType' object has no attribute 'tobytes'               

Any quick ideas on a fix for that?  Thanks -

Trill

0 Kudos
XanderBakker
Esri Esteemed Contributor

Strange... If you had to make that change on line 16, you may as well change it on line 35 (I guess).

I think the code does not account for a feature without attachment. Is that the case for you? It would be nice if I could look at a small part of the data.

Kind regards, Xander

0 Kudos
TrilliumLevine1
Occasional Contributor

Hi Xander,

Thanks a lot for taking the time to post this, I appreciate it!

Best regards

0 Kudos
TrilliumLevine1
Occasional Contributor

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:

  1. Functionality to create a directory for attachments and another for the spatial data.
  2. Functionality for unzipping and renaming the replicated geodatabase.
  3. I need this to run daily and delete the download from 'yesterday', so I added functionality for that.
  4. I also wanted to have the global id in the file name, and for it to add a file extension to the attachment even if one wasn't included as part of the the file name -- functionality for that is added.
  5. As far as I can tell the base code works only for images, but since attachments can be virtually any format, I modified the code to handle any format.
  6. Generate a report showing number of attachments downloaded per layer in feature service.

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

TrilliumLevine1
Occasional Contributor

Hi Xander,

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!

Trill

0 Kudos
XanderBakker
Esri Esteemed Contributor

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.

0 Kudos