Updating Data Source in ArcGIS PRO project with arcpy

3962
23
03-22-2019 10:55 AM
Arne_Gelfert
Regular Contributor

Trying to update data source for layers in ArcGIS Pro maps programmatically. So, I must be misunderstanding the syntax for doing that explained here. Because the following does not work:

import arcpy

aprx = arcpy.mp.ArcGISProject(r'path to my project file')

#This gets me list of all the maps
maplist = aprx.listMaps()

#If I only want those belonging to MyGroup
mygroup = aprx.listMaps('MyGroup')[0]

#To get the layers in that group
grouplayers = mygroup.listLayers()

new_sdeConn = r'path to my SDE connection file'

for lyr in grouplayers:
old = lyr.connectionProperties #also tried lyr.connectionProperties['connection_info']
lyr.updateConnectionProperties(old, new_sdeConn)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

This doesn't throw an error. it just doesn't do update the data sources as desired. The ESRI example goes like:

aprx.updateConnectionProperties(r'C:\Projects\YosemiteNP\Vector_Data\Yosemite.gdb',
r'C:\Projects\YosemiteNP\DBConnections\Server.sde')‍‍‍‍

Does this maybe only work for the project as a whole?

Reply
0 Kudos
23 Replies
StephenM
Occasional Contributor II

The issue you're having is that lyr.connectionProperties returns a dictionary but your new connection is a workspace path. You just need to access the right key in the dictionary:

for lyr in grouplayers:
    old = lyr.connectionProperties['connection_info']['database']
    lyr.updateConnectionProperties(old, new_sdeConn)
Reply
0 Kudos
Arne_Gelfert
Regular Contributor

Stephen, thanks. Appreciate you chiming. I realize that connection_info is a dictionary. But I wasn't sure how to use it. Keyword "database' only updates the database. I'm actually trying to switch this to use a different account (new 'user' and 'password') and was hoping to do so using a new SDE connection file. Can you maybe not to do?

If you look at the other keys in the dict, I need more than 'database' to be updated.

{'authentication_mode': 'DBMS',
'database': 'Prod',
'dbclient': 'sqlserver',
'db_connection_properties': 'myserver',
'password': '<*********>',
'instance': 'sde:sqlserver:myserver',
'server': 'myserver',
'user': 'myaccount',
'version': 'dbo.DEFAULT'}

I am not an expert on these SDE connection files. But my understanding has always been that they store a reference to DB server/instance,  DB name, authentication (and/pr password). So basically what's in the dictionary above. So merely updating 'database' in the dict wouldn't be sufficient, I think. To be safe, I tried it, and to no effect.

Reply
0 Kudos
StephenM
Occasional Contributor II

Ah, right. I forgot that you're using SDE connections. To switch users I'd try modifying ['connection_info]['user'] and ['connection_info']['password'].

for lyr in layers:
old_conn = lyr.connectionProperties
new_conn = old_conn
new_conn['connection_info']['user'] = new_user
new_conn['connection_info']['password'] = new_pw
lyr.updateConnectionProperties(old_conn, new_conn)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Reply
0 Kudos
Arne_Gelfert
Regular Contributor

I've tried passing in a complete new dict or just the 'user' and 'password' values as you suggested. I've tried the approach of referencing another layer's connectionProperties suggested here:

lyr = m.listLayers('some other layer')[0]
l.updateConnectionProperties(l.connectionProperties, lyr.connectionProperties)

None of it is working. Darn!

Reply
0 Kudos
StephenM
Occasional Contributor II

Hm, maybe the credentials can't be modified in the way the other values can. I do notice that there aren't examples in the documentation that show changing users in the connection properties. I had some success changing a connection from an OS authentication connection to a DBMS connection, but I don't have multiple named DB users to test changing credentials.

Reply
0 Kudos
BrettLessner
New Contributor III

Has anyone solved this? I'm trying to move a workflow from Map to Pro, and this is hanging me up. It was so much easier with the lyr.replaceDataSource(). 

TobiSellekaerts
New Contributor III

Sadly I have given up banging my head against the desk trying to make this work.  I have searched through three other threads on GeoNet of people having a variation of this same problem without resolution:

updateConnectionProperties 

ArcPy Layer updateConnectionProperties not working as expected 

Replacing datasource does not work through arcpy 

and elsewhere:

Repoint enterprise geodatabase connection using ArcPy in ArcGIS Pro - Geographic Information Systems... 

In the end I found an old ArcMap .mxd with the same data also pointing to the wrong database, used good ole reliable lyr.replaceDataSource() to fix the data sources, imported the mxd as a new map in Pro, then copied the data over into my original map.  Sad but true.

Arne_Gelfert
Regular Contributor

As with so many other instances, not finding any info on how to do it, I abandoned this a while back. But I'm sure I will have to look at it again some day and will remember this post.

Reply
0 Kudos
MichaelVolz
Esteemed Contributor

Tobi:

I have not tried to recreate my update SDE datasource scripts from ArcMap to Pro yet so I have not experienced this hardship yet, but I have found that the Set Data Source(s)... functionality of ArcCatalog has not been ported over to Pro.  Although this ArcCatalog functionality does not work on batch mxds, I have found it very useful for moving publishing mxds from development to test to production where the SDE database is different for each environment.

How many Pro aprxs are you looking to update the SDE connection properties for?

Set Data Sources Tool in Pro

Reply
0 Kudos