English

How To: Use Python to update multiple definition queries

Summary

Updating multiple definition queries for layers in a map document can be a time-consuming process, but this process can be automated using Python.

Procedure

The following script iterates over each map document file (.mxd) in a directory and searches each layer in the Table Of Contents for a definition query. If found, the layer's definition query is scanned for the presence of the string found in each key of the 'expressions' dictionary. The replacement string is the associated value. Before running the script, users must ensure they have updated the following lines:

26: String representing the directory of the MXD file(s).

28: The dictionary containing strings to be searched for [these are the keys] and replaced [with the values].

For example, in the script below, if 'shape_length' is found in any definition query, it is replaced with 'SHAPE STLength()'.

Code:
'''
UpdateDefinitionQuery.py
Andrew Ortego
11/11/2015
Purpose:
Updates a subsection of a layer's Definition Query.

Work Flow:
Iterates over each Map Document file (.mxd) in a directory and
searches each layer in the Table of Content for a definition
query. If found, the layer's definition query is then scanned
for the presence of the string seen in each key of the
'expressions' dictionary. The replacement string is the
associated value.
Input:
(26) String representing the directory of the MXD file(s).
(28) Dictionary containing strings to be searched for
[these are the keys] and replaced [with the values].
Output:
A copy of each MXD with the newly updated Definition Query.
'''

from os import path
from arcpy import env, mapping

env.workspace = ws = "MXD DIRECTORY"

expressions = {
"original_pattern" : "new_pattern",
"original_pattern2" : "new_pattern2",
}

mxds = [mapping.MapDocument(m) for m in arcpy.ListFiles("*.mxd")]

for i, mxd in enumerate(mxds):
layers = [l for l in mapping.ListLayers(mxd) if l.isFeatureLayer and l.definitionQuery]

for lyr in layers:
for old_exp, new_exp in expressions.iteritems():
if old_exp in lyr.definitionQuery:
lyr.definitionQuery = lyr.definitionQuery.replace(old_exp, new_exp)

mxd.saveACopy(path.join(ws, "COPY_{0}_" + mxd.filePath + ".mxd".format(i)))
del mxd

Note:
This script utilizes the 'iteritems' function, which has been removed from Python 3. If updating this script to run with ArcGIS Pro, users must update the 'iteritems' function and also iterate over Projects instead of MXDs.