Ok. I've been trying to work with the script (below) but having a few dilemmas that I am hoping someone can help me with. (1) The text file needs the Database Connection name, but it's the 'friendly' name that we use in ArcCatalog, which could be different for every user. Is there a way to instead reference the Server, Service, and Database?(2) I ran a test where I was trying to replace the contours for a new version. We have contours for multiple counties. What happened was that it ran through the list and only looked for the feature class name and not a match with the owner and feature class name. i.e. I was trying to change PTD.CONTOURS_JEFF to PTD.cn but when it scanned through the connection the script came across BULLITT.cn and assigned it instead of looking for a full match.(3) Is there a way to tell the script to keep the python / command window open after it processes so we can make sure everything processed ok? When it errors out it closes in a snap and there is no way to see what the message said.This script is much more in depth to Python than I have gotten so it's taking me a while to troubleshoot this. Any help would be HUGE!!! THANK YOU for reading this and any assistance you can give me! Here is the script:#!/usr/bin/env python
# -*- coding: utf-8 -*-
# for test.txt file
# Layername or Source, Layername or SourcePath, Connect To, Featureclass
__doc__ = """ """
import os, sys
import arcpy
from arcpy import env
from optparse import OptionParser
def get_all_files(options, startpath, filter):
""" Build a list of files in a directory, recursively
(optionally) as default. """
files = []
for filename in os.listdir(startpath):
f = os.path.join(startpath,filename)
if os.path.isdir(f) and not options.norecurse:
#print "Directory found: %s" % (f)
result = get_all_files(options, f, filter)
if result is not None:
files += result
if f.upper().endswith(filter.upper()):
files.append(f.upper())
if files is not None and len(files) > 0:
files.sort()
return files
def get_files(options):
""" Get files from command line """
files = options.filelist.upper().split(",")
return files
def changeDataSource(options, filelist):
env.workspace = options.workspace
if filelist is not None:
for file in filelist:
print "Processing %s" % (file)
changed = False
mxd = arcpy.mapping.MapDocument(file)
layerList = arcpy.mapping.ListLayers(mxd)
for layer in layerList:
if layer.supports("DATASOURCE"):
if options.listonly:
print "\tLayer %s connects to %s" % (layer.name, layer.dataSource)
else:
checkIt = inList(layer.name, layer.dataSource)
if checkIt is not None:
print "\tMatch found for %s" % (layer.name)
try:
#print os.path.join(env.workspace,checkIt[1][0])
if options.force:
# will change the document without workspace/featureclass checks
layer.replaceDataSource(checkIt[1][0],options.workspacetype,checkIt[1][1],False)
else:
# will only work if a valid workspace
layer.replaceDataSource(checkIt[1][0],options.workspacetype,checkIt[1][1],True)
changed = True
print "\tDatasource for %s channged to %s" % (layer.name,checkIt[1][1])
except Exception as e:
print "\tCound not change datasource in %s for %s.\n\t%s\n\n\tIf no error number returned, the most likely\n" \
"\tcause is an invalid workspace." % (file,layer.name,e)
if not options.force:
print "\tYou can force it to change with --force option.\n"
if not options.listonly and changed:
mxd.save()
else:
print "Empty file list."
return
def inList(layername, layersource):
global filecontents
for i in filecontents['layer']:
if i[0].upper() == layername.upper():
return i
for i in filecontents['source']:
if i[0].upper() == layersource.upper():
return i
return None
def readfile(file):
layer = []
source = []
linecnt = 0
contents = open(file,"r")
for line in contents:
if line[0:1] != "#":
linecnt += 1
parts = line.split(",")
x = []
xx = []
xx.append(parts[2].strip())
xx.append(parts[3].strip())
x.append(parts[1].strip())
x.append(xx)
if parts[0].upper().strip() == "LAYERNAME":
layer.append(x)
elif parts[0].upper().strip() == "SOURCE":
source.append(x)
else:
print "Invalid entry: %s" % (parts[0].upper().strip())
del xx
del x
contents.close()
print "Read %i lines. (excluding comments)" % (linecnt)
return {'layer':layer,'source':source}
def formatstring(string):
layer = []
source = []
parts = string.split(",")
x = []
xx = []
xx.append(parts[2].strip())
xx.append(parts[3].strip())
x.append(parts[1].strip())
x.append(xx)
if parts[0].upper().strip() == "LAYERNAME":
layer.append(x)
elif parts[0].upper().strip() == "SOURCE":
source.append(x)
else:
print "Invalid entry: %s" % (parts[0].upper().strip())
del xx
del x
return {'layer':layer,'source':source}
if __name__ == '__main__':
parser = OptionParser(usage='usage: %prog [options]', version='0.1')
parser.add_option('--filelist', action='store', dest='filelist', default=None,
type='string', help='List of files to process.')
parser.add_option('--dirpath', action='store', dest='dirpath', default='C:\\',
type='string', help='Path to walk.')
parser.add_option('--filter', action='store', dest='filter', default='.MXD',
type='string', help='File filter. ie. .MXD')
parser.add_option('--workspace', action='store', dest='workspace', default=None,
type='string', help='Path to the workspace.')
parser.add_option('--workspacetype', action='store', dest='workspacetype', default="SDE_WORKSPACE",
type='string', help='Workspace type. Default "SDE_WORKSPACE".')
parser.add_option('--infile', action='store', dest='infile', default=None,
type='string', help='Input pivot file.')
parser.add_option('--dest', action='store', dest='dest', default=None,
type='string', help='Reassignment string.\n\t' \
'ie. "Layername,Artwork,Database Connections\PublicUser.sde,SDE.Artwork"')
#boolean
parser.add_option('--force', action='store_true', dest='force', default=False,
help='Force document update without checking if valid.')
parser.add_option('--listonly', action='store_true', dest='listonly', default=False,
help='Only list the sources found. Do not replace.')
parser.add_option('--norecurse', action='store_true', dest='norecurse', default=False,
help='Do not recurse directories.')
(options, args) = parser.parse_args()
# this really isn't necessary i do not believe.
if options.workspace is None:
options.workspace = os.environ['APPDATA']+"\ESRI\Desktop10.0\ArcCatalog"
files = get_all_files(options, options.dirpath, options.filter) if options.filelist is None else get_files(options)
if options.infile is not None or options.dest is not None:
if options.infile is not None:
filecontents = readfile(options.infile)
else:
filecontents = formatstring(options.dest)
changeDataSource(options, files)
This is what I've been experimenting with, but the "GIS_LOJIC.sde" is just how I have it referenced on my machine. Source,Database Connections\GIS_LOJIC.sde\PTD.AIRPORTS_JEFF,Database Connections\GIS_LOJIC.sde,PTD.apSource,Database Connections\GIS_LOJIC.sde\PTD.CONTOURS_JEFF,Database Connections\GIS_LOJIC.sde,PTD.cnSource,Database Connections\GIS_LOJIC.sde\PTD.HL_LINE_JEFF,Database Connections\GIS_LOJIC.sde,PTD.hl_line