Batch extract attachments from File Geodatabase into individual folders based on features

1391
2
04-02-2019 01:55 AM
ColinBourne1
New Contributor II

Just wondering if anyone has a script to batch extract attachments from a file geodatabase and save them into individual folders based on the point/lines or polygons that they are attached to?

Kind Regards

Colin Bourne

0 Kudos
2 Replies
ThomasJones1
Esri Contributor

Hello Collin,

There is a technical article which goes through process of batch exporting attachments from a feature class in ArcMap. The script runs per feature class so you would need to run it multiple times for each point line and polygon feature class. The script also allows you to define an output directory for each attachments table.

Hope this helps!

Technical Support - How To: Batch export attachments from a feature class in ArcMap:

https://support.esri.com/en/technical-article/000011912

Thanks,

Thomas.

0 Kudos
DougBrowning
MVP Notable Contributor

I do it this way.  I get the names via relates since I need to.

#-------------------------------------------------------------------------------
# Name:        Survey123 Export Photos to File System.py
# Purpose:     Exports the photos from the Survey123 Photos form from a exported GDB
#               Assumes state dir is already there
#               Will check for and create PrimaryKey dir if needed
#               For now it will overwrite every file as it goes.  Plus and minus to this.
#
# Author:      dbrowning
#
# Created:     10/31/2018
# Modified:    10/31/2018
#
#
#
#-------------------------------------------------------------------------------

import os, arcpy

# vars--------------------
inDB = r"Survey123InputDataOct11.gdb"
# to get the names and PrimaryKey
photoForm = "AIMPhotos"
# actual attachements table
attachName = "AIMPhotos__ATTACH"

outDir = r"SurveyTest\Photos"

# should be standard
fldBLOB = 'DATA'
fldAttName = 'ATT_NAME'

dateLoadedInDb = "2018-09-01"

# vars--------------------

# join to AIMPhots form to get the PrimaryKey and state info
# Note the first year they called it PlotKey instead
arcpy.MakeTableView_management(inDB + "\\" + attachName, "attachView")
arcpy.AddJoin_management("attachView", "REL_GLOBALID", inDB + "\\" + photoForm, "globalid")
# funky due to the join
fieldList = [attachName + "." + fldBLOB, attachName + "." + fldAttName, photoForm + ".PlotKey", photoForm + ".Office", photoForm + ".filename_T1", photoForm + ".filename_T2", photoForm + ".filename_T3" \
            ,photoForm + ".filename_Soil1", photoForm + ".filename_Soil2", photoForm + ".filename_Soil3", photoForm + ".MiscPhoto1filename", photoForm + ".MiscPhoto2filename", photoForm + ".MiscPhoto3filename"]
with arcpy.da.SearchCursor("attachView", fieldList) as cursor:
   for row in cursor:
      binaryRep = row[0]

      # save to disk
      # build output path of base + State + PrimaryKey (PlotKey + DateLoadedInDb)
      # for now need to check for blank PlotKey and blank Office - which should be fixed already
      if row[3] == None or row[2] == None:
        print "Warning Null values found in the Office or PlotKey field.  Skipping photo.  Must fix!!"
        print "   ATT_NAME is " + row[1]
      else:
        baseOut = outDir + "\\" + row[3][:2] + "\\" + row[2] + dateLoadedInDb
        # check to see if already PrimaryKey dir there - if not create it
        if not os.path.exists(baseOut):
            os.makedirs(baseOut)

        # Need to get the actual file name from the right field.  No real other way to do it with a SC so had to write it out
        whichPhoto = row[1].split("-")[0]
        if whichPhoto == "T1":
            fileName = row[4] + ".jpg"
        elif whichPhoto == "T2":
            fileName = row[5] + ".jpg"
        elif whichPhoto == "T3":
            fileName = row[6] + ".jpg"
        elif whichPhoto == "Soil1":
            fileName = row[7] + ".jpg"
        elif whichPhoto == "Soil2":
            fileName = row[8] + ".jpg"
        elif whichPhoto == "Soil3":
            fileName = row[9] + ".jpg"
        elif whichPhoto == "MiscPhoto1":
            fileName = row[10] + ".jpg"
        elif whichPhoto == "MiscPhoto2":
            fileName = row[11] + ".jpg"
        elif whichPhoto == "MiscPhoto3":
            fileName = row[12] + ".jpg"

        # in case some / got in there.  this should not happen now!
        fileName = fileName.replace("/","")

        # save out the file
        open(baseOut + os.sep + fileName, 'wb').write(binaryRep.tobytes())


del cursor