Hi, I am trying to change the data source of our parcel fabric that is not being maintained to a new one stored in the same SDE dataset. I have created a script to the best of my ability and I get this error. I have searched for possible solutions all day. I am sure it's a simple solution but this is time sensitive and I need to figure out what I am doing wrong as soon as possible. Thanks for any help you can offer.
ERROR:
if lyr.name == "Fernie Parcel":
NameError: name 'lyr' is not defined
---------------------------------------------------------------------------------------------------------------------------------------
import arcpy
from arcpy import env
from arcpy import mapping
arcpy.env.workspace = workspace = r"P:\mxd_data_source"
arcpy.env.overwriteOutput = True
mxdList = arcpy.ListFiles("*.mxd")
for mxd in mxdList:
mxd = workspace + "\\" + mxd
print mxd + " is being processed"
mxd = arcpy.mapping.MapDocument(mxd)
for df in arcpy.mapping.ListDataFrames(mxd, "*"):
if lyr.name == "Fernie Parcel":
lyr.replaceDataSource(workspace, "SDE_WORKSPACE", "parcel_pmbc", validate=True)
print "Successfully updated data sources"
mxd.save()
It doesn’t look like you have iterated over any layers in your mxd yet ...
for lyr in arcpy.mapping.ListLayers(df):
so it’s saying it can’t find ‘lyr’
Thanks Jeff,
I entered the line. It said it works but the link is broken and points to P:\mxd_data_source as being my database. Instead of my SDE. I am guessing I need to run another broken link script. Cheers!
Data Source
Data Type: SDE Feature Class
Feature Class: parcel_pmbc
Database: P:\mxd_Data_source
Feature Dataset: xxxx.SDE.Parcels
Feature Type: Simple
Geometry Type: Polygon
New Script
import arcpy
from arcpy import env
from arcpy import mapping
arcpy.env.workspace = workspace = r"P:\mxd_data_source"
arcpy.env.overwriteOutput = True
mxdList = arcpy.ListFiles("*.mxd")
for mxd in mxdList:
mxd = workspace + "\\" + mxd
print mxd + " is being processed"
mxd = arcpy.mapping.MapDocument(mxd)
for df in arcpy.mapping.ListDataFrames(mxd, "*"):
for lyr in arcpy.mapping.ListLayers(df):
if lyr.name == "Fernie Parcel":
lyr.replaceDataSource(workspace, "SDE_WORKSPACE", "parcel_pmbc", validate=True)
print "Successfully updated data sources"
mxd.save()
Are you running this script while the mxd is open or closed?
Hi Jeff, All mxds are closed. There are 180 mxds. I did this in a test folder for now.
Cheers,
Ok, According to the replaceDataSource method docs, the first parameter in the method is the workspace you want it to be changed to. Assign pathToSDEConnection to your sde connection file.
try this:
arcpy.env.workspace = workspace = r"P:\mxd_data_source"
pathToSDEConnection = r'Path to your connection file'
# arcpy.env.overwriteOutput = True
mxdList = arcpy.ListFiles("*.mxd")
for mxd in mxdList:
mxdpath = workspace + "\\" + mxd
print mxd + " is being processed"
mxdMd = arcpy.mapping.MapDocument(mxdpath)
for df in arcpy.mapping.ListDataFrames(mxdMd, "*"):
for lyr in arcpy.mapping.ListLayers(df):
print lyr.name
if lyr.name == "Fernie Parcel":
arcpy.AddMessage("Updating connections: {}".format(lyr.name))
lyr.replaceDataSource(pathToSDEConnection, "SDE_WORKSPACE", "parcel_pmbc", validate=True)
mxdMd.save()
print("Done updating data sources in {}".format(mxd))
We are getting there!! It works beautifully for the first mxd. Then I get an unexpected error: ValueError: Layer: Unexpected error Database Platform: SQL Server. This is when I have the validate set to True. When I change it to False, It runs through all the mxds successfully but my links are broken except for the first one which works. Cheers!
First successful mxd data source:
Data Type: SDE Feature Class
Database Platform: SQL Server
Server: sql
Connection Properties: sql
Authentication Type: Operating system authentication
Database: C
Version: sde.DEFAULT
Description: Instance default version.
Feature Dataset: C.SDE.Base
Feature Class: C.SDE.parcel_pmbc
Feature Type: Simple
Geometry Type: Polygon
Coordinates have Z values: Yes
Coordinates have measures: No
Second mxd data source
Data Type: SDE Feature Class
Feature Class: parcel_pmbc
SERVER: sql
INSTANCE: sde:sqlserver:sql
DBCLIENT: sqlserver
DB_CONNECTION_PROPERTIES: sql
Database: C
IS_GEODATABASE: true
AUTHENTICATION_MODE: OSA
CONNPROP-REV: Rev1.0
VERSION: sde.DEFAULT
Feature Dataset: C.SDE.Base
Feature Type: Simple
Geometry Type: Polygon
Are they different datasources between the mxds? The first one pointing to your workspace and the others pointing to a dataset in a SQL server? I can't tell if this will work because I don't know all your datasource paths but if they are different you will have to test and process those separately. For example, testing for the 'workspace' path in the datasource:
arcpy.env.workspace = workspace = r"P:\mxd_data_source"
arcpy.env.overwriteOutput = True
mxdList = arcpy.ListFiles("*.mxd")
for mxd in mxdList:
mxdpath = workspace + "\\" + mxd
print mxd + " is being processed"
mxdMd = arcpy.mapping.MapDocument(mxdpath)
for df in arcpy.mapping.ListDataFrames(mxdMd, "*"):
for lyr in arcpy.mapping.ListLayers(df):
if lyr.name == "Fernie Parcel":
if lyr.supports("DATASOURCE"):
if workspace in lyr.dataSource:
print "Updating connections: {}".format(lyr.name)
lyr.replaceDataSource(workspace, "SDE_WORKSPACE", "parcel_pmbc", validate=True)
else:
print "{} in {} does not support Datasource.".format(lyr.name, mxd)
mxdMd.save()
print("Done updating data sources in {}".format(mxd))
Hi Jeff,
The workspace is where my mxds are sitting.
The two feature classes that I am working with are in the same dataset in the SDE. Database Connections\User on DEFAULT.sde\COF.SDE.Base. Thanks,
I ran a the script to list layer source. The sources do point to this data source originally if that helps. This is a learning experience, thank you!
C:\Users\username.CF\AppData\Roaming\ESRI\Desktop10.4\ArcCatalog\CF on SQL-DEFAULT.sde\CF.SDE.Base