I was given a bulk batch of lyr files that were converted to lyrx files with paths to a file gdb that is no longer in operation. All of the feature classes I would like to redirect the the lyrx files to are on an Enterprise GDB which connects through an sde connection file housed on a networked server.
Any time I add a lyrx file to a map and change its data source, it only holds for that particular project. It also sets the source to a local drive temp path, even though I set its connection to the sde connection file. Is there any method to permanently change the data source of a lyrx file in bulk like in ArcCatalog, or through some python script?
This seems like a major ESRI oversight. Thanks for the help!
Solved! Go to Solution.
Hi Derek,
The thing is that your content is located on fileshare. We need to amend a bit your paths, therefore.
Also, it is better to create new files, instead of overwriting existinig ones. Simply, in case of a failure, these files may get corrupted.
Please check the following code. Hopefully, it works for you.
import arcpy
import os
filesDirectory = r"\\\\svgcisilon.path\\gis\\Mitigation"
fileExt = r".lyrx"
files = [os.path.join(filesDirectory, f) for f in os.listdir(filesDirectory) if f.endswith(fileExt)]
for file in files:
lyrFile = arcpy.mp.LayerFile(file)
lyrFile.updateConnectionProperties(r"\\\\svgcisilon.path\\gis\\MitigationLayers\\MitigationBanks.gdb", r"\\\\svgcisilon.path\\gis\\envi@sv03.sde")
lyrFile.saveACopy(file.split(".lyrx")[0] + "SDE.lyrx")
BR,
Adam
If the Feature Class Names of FGDB are same as the Feature Class Names in SDE, then you could follow these steps.
1. Add all the LYRX files to ArcGIS Pro Map View. Click on the red exclamation mark next to any one layer, and connect it to the SDE Feature Class path.
This should automatically correct the path of all the available layers (if the feature class names match), and all are present in the same sde path.
2. Check if any layer remains unfixed. Try to manually connect it to right data source, if required.
3. In Geoprocessing Pane search for "Save to Layer File" > Right-click the tool > Click Batch.
You may choose to save the Batch tool for future use.
Fill the required parameters. Select all the files from Table of Content, drag and drop to "Input Layers" parameter.
For Output Layer, choose an appropriate folder, and type %Name%.lyrx
If you want to batch modify a bunch of lyrx files the way to do this is using ArcGIS Pro's mapping module, arcpy.mp. In Python you can read each lyrx, modify its source, and overwrite the lyrx with the updated source.
https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/updatingandfixingdatasources.htm
https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/layerfile-class.htm
A useful arcpy method to find all the lyrx files and loop through them is arcpy.da.walk():
https://pro.arcgis.com/en/pro-app/latest/arcpy/data-access/walk.htm
Hi Derek,
you can try the following python code in ArcGIS Pro Python window. Adjust the paths.
import arcpy
import os
filesDirectory = r"C:\Projects\YosemiteNP"
fileExt = r".lyrx"
files = [os.path.join(filesDirectory, f) for f in os.listdir(filesDirectory) if f.endswith(fileExt)]
for file in files:
lyrFile = arcpy.mp.LayerFile(r"C:\Projects\YosemiteNP\Yosemite.lyrx")
lyrFile.updateConnectionProperties(r"C:\Projects\YosemiteNP\Vector_Data\Yosemite.gdb", r"C:\Projects\YosemiteNP\DBConnections\Server.sde")
lyrFile.saveACopy(file.split(".")[0]+ "New.lyrx")
Hope this helps,
Adam
Just a couple of curiosities,
lyrFile = arcpy.mp.LayerFile(r"C:\Projects\YosemiteNP\Yosemite.lyrx")
In this specific line, you you pointing to any random lyrx in the directory and then the following lines will update the path for all lyrx?
lyrFile.updateConnectionProperties(r"C:\Projects\YosemiteNP\Vector_Data\Yosemite.gdb", r"C:\Projects\YosemiteNP\DBConnections\Server.sde")
lyrFile.saveACopy(file.split(".")[0]+ "New.lyrx")
Also, in these lines, is it taking the .gdb path the original path in the lyrx files and the .sde the new?
Thanks,
Derek
1. That's a bug, @nita14 meant to put the variable file in the place of the .lyrx path.
2. Yes, for both these items, see the documentation for the LayerFile object and its updateConnectionProperties method.
Thanks for the reply.
For part 1.
lyrFile = arcpy.mp.LayerFile(r"C:\Projects\YosemiteNP\Yosemite.lyrx")
forgive my ignorance, but you're literally just replacing that with:
lyrFile = arcpy.mp.LayerFile(r"file") or lyrFile = file?
I'm guessing:
lyrFile = arcpy.mp.LayerFile(file)
The code above it (apparently) builds the full path to the lyrx files in a list and loops through them one by one.
This updateConnectionProperties method has some pretty fancy syntax options using dictionaries, so I can't vouch for this untested code. (I haven't had time to whip up code which is why I simply pointed you to the relevant doc pages.)
Hi,
Indeed there was a bug. This snippet works for me:
import arcpy
import os
filesDirectory = r"C:\_temp" #Dirctory in which you store the lyrx files
fileExt = r".lyrx" #do not change it
files = [os.path.join(filesDirectory, f) for f in os.listdir(filesDirectory) if f.endswith(fileExt)] #do not change it
for file in files:
lyrFile = arcpy.mp.LayerFile(file)
lyrFile.updateConnectionProperties(r"C:\_temp\test1.gdb", r"C:\_temp\test1_1.gdb") #path to old database and path to new database (.sde file in your case)
lyrFile.saveACopy(file.split(".")[0]+ "New.lyrx")
Comments are after # sign. Amend the paths and try it.
BR,
Adam
Hey Adam!
Thanks for the reply, I ran the bit you suggested above and i am running into an error with the lyrfile.saveAcopy portion. See my example below:
import arcpy
import os
filesDirectory = r"\\svgcisilon.path\gis\Mitigation" #Dirctory in which you store the lyrx files
fileExt = r".lyrx"
files = [os.path.join(filesDirectory, f) for f in os.listdir(filesDirectory) if f.endswith(fileExt)]
for file in files:
lyrFile = arcpy.mp.LayerFile(file)
lyrFile.updateConnectionProperties(r"\\svgcisilon.path\gis\MitigationLayers\MitigationBanks.gdb", r"\\svgcisilon.path\gis\envi@sv03.sde")
lyrFile.saveACopy(file.split(".")[0]+ "SDE.lyrx")
If i didnt really mind whether or not a copy was saved could i just change line 10 to "lyrFile.save()" instead?
Furthermore, I am receiving an error when running the script as is:
Traceback (most recent call last):
File "<string>", line 10, in <module>
File "c:\program files\arcgis\pro\Resources\arcpy\arcpy\_mp.py", line 831, in saveACopy
return convertArcObjectToPythonObject(self._arc_object.saveACopy(*gp_fixargs((file_name,), True)))
OSError: \\svgcisilonSDE.lyrx
Do i need to include the path to the directory where the lyrx file should be saved before file.split?
Again, thank you for your help.