I've been tasked with updating attribute table fields with file paths to image files in a folder based on a unique ID. I'm having trouble thinking up a script that will do this? I'm working on a standalone script in ArcGIS Pro 2.3.1 Arcpy.

This is an example of how the table should look. Every JPG has a unique ID that matches the Post_Number field unique ID. Currently, the paths to the JPGs are entered manually into the table, and there are 1000s of them.

enter image description here

I don't think a Calculate Field will work because not all JPGs are stored in the same directory. All I've done so far is create a cursor that searches the Post_Number and Photo fields.

#for each row print the fields with arcpy.da.SearchCursor(fc, fields) as cursor: for row in cursor: print(u"{0}, {1}".format(row[0], row[1]))

  • Create a tool with 1st parameter = raster dataset, multiple. Do search in Windows explorer, select results, drag and drop them to parameter box. Hope the rest is obvious - extact id from file name to make join. – FelixIP Mar 19 at 21:25

Because my reputation implies in comment limits I need to assume you already had the 'Post_Number' field filled when the geometry for a photo is created, so the script below just search for the photos and fills the 'Photo' field with the full path:

import fnmatch
import os

# Directory/unity where search begins
src = 'C:\\'

# List of files with complete path and filename
matches = []
rowM = [None, None]

# Counters for log purposes
count1 = 0
count2 = 0

print 'Beginning search of photos'

for root, dirnames, filenames in os.walk(src):
    count1 += 1
    print count1
    for filename in fnmatch.filter(filenames, '*.jpg'):
        count2 += 1
        rowM[0] = os.path.join(root, filename) # complete path
        rowM[1] = os.path.join(filename[:-4]) # filename without extension

import arcpy

fc = 'C:\Teste\Teste.gdb\Teste_pto'
fields = ['Post_Number', 'Photo']
expression = fields[1] + ' IS NULL'

print 'Beginning search of paths'

    with arcpy.da.UpdateCursor (fc, fields, expression) as uc:
        for line in uc:
            for row in matches:
                if (line[0] == row[1]): # if Post_Number matches filename
                    line[1] = row[2] # Photo is equal to path
except arcpy.ExecuteError:

print 'End of script'
  • thanks for the post. Where is fnmatch defined? And, yes, the Post_Number field is already filled. – Pfalbaum Mar 27 at 15:19
  • 1
    I'm using Python 2.7, and fnmatch is a module (note the first line). More information in Python documentation: docs.python.org/2/library/fnmatch.html – Lucas Mar 27 at 15:27
  • It runs through without error, but the Photo field in the table doesn't get populated. – Pfalbaum Mar 27 at 16:07
  • 1
    Are you using a normal gdb or a sde connection? If you are using a sde connection, it can be necessary to start a edit session. Use a try: update code except arcpy.ExecuteError: arcpy.AddMessage(str(arcpy.GetMessages(2))) structure to see the error messages. – Lucas Mar 27 at 16:17
  • Lucas, I wasn't sure what the purpose of expression variable was so I removed it. Then your script worked fine. – Pfalbaum Mar 27 at 18:25

This script worked well too:

import arcpy, os

ws = r'pathTo\JPGsdirectory'
jpgs = {} # empty dictionary

for dirName, subdirList, fileList in os.walk(ws): #iterate the directory
    for fname in fileList:
        jpgs[fname[:-4]] = os.path.join(dirName,fname) #create key:value pairs dictionary

fc = r'pathTo\featureclass\WCDOT_Signs'
fields = ['OID@', 'Post_Number', 'Photo']

with arcpy.da.UpdateCursor(fc, fields) as cursor:
    for row in cursor:
            row[2] = jpgs[row[1]]
        except KeyError:
            print("No photo for: {}".format(row[1]))

del cursor

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.