Geographic Information Systems Asked by BrianPeasley on March 2, 2021
I have some Python code that is launched from within an ArcMap project. Any joins that the user may have created in the project must be removed in order for my code to run. Unfortunately, the code that removes a join… arcpy.RemoveJoin_management(“layer1”, “layer2”)… also breaks some of the layer properties that are critical to my application (highlighted fields, read-only fields, etc).
If joins are removed by right-clicking the layer in ArcMap and choosing “Remove Joins” the layer properties are left intact.
If I can detect that a join exists from within my code, I will simply exit the code and display a message that the user must manually remove their joins before attempting to run the code. So… Can a Join be detected programmatically?
Too bad there's not a hasJoin property on the arcpy.Layer class. I think you can test for a join by looking at field names though. Here's a simple proof of concept for data in a file geodatabase:
import arcpy, arcpy.mapping as arc
def joinCheck(lyr):
fList = arcpy.Describe(lyr).fields
for f in fList:
if f.name.find(lyr.datasetName) > -1:
return True
return False
arcpy.env.workspace = r'<path_to_your_gdb>'
mxd = arc.MapDocument(r'<path_to_your_mxd>')
lyrs = arc.ListLayers(mxd)
for lyr in lyrs:
# ignore group layers
if not lyr.isGroupLayer:
hasJoin = joinCheck(lyr)
if hasJoin:
print 'nFound a join: %s.' % lyr.datasetName
else:
print 'nNo join found on %s.' % lyr.datasetName
Correct answer by Derek Swingley on March 2, 2021
I think you will find that there is no bulletproof way to do this with GP objects, you'll need to use ArcObjects and comtypes. Here's some discussion from the ESRI forums on the difficulties in checking for joins with the standard GP tools/objects: https://geonet.esri.com/thread/20317
Answered by blah238 on March 2, 2021
In answer to comment above, arcpy.RemoveJoin_management raises an exception if there are no joins on the table. Also, ArcPy does not support update cursors on joined tables, even if the field being updated is in the base table. However, you can put arcpy.RemoveJoin_management inside a try block with no action on the exception if there are no joins.
A workaround to how to do an update from a field in a joined table is to create a dictionary from the the table that would be joined and use it as a lookup for the value of the non-key fields using the key field.
In this example code fragment, I have a table named LOCNAME which has a unique key field named "Loc_name" (which identifies a particular level of a composite address locator) and a non-key field "Descript" which gives a text description of the particular level.
I have already added the "Descript" field to the attribute table of a geocoded address list thisLayer containing the field "Loc_name" that identifies which level that particular address was geocoded, and I want to update the value of "Descript" using the corresponding value from the LOCNAME table.
try:
arcpy.RemoveJoin_management(thisLayer)
except:
pass
thisLayerDataSource = thisLayer.dataSource
theDescriptDict = {}
theLOCNAMECursor = arcpy.SearchCursor(theLOCNAMEDataSource)
for theLoc_name in theLOCNAMECursor:
theDescriptDict[theLoc_name.getValue("Loc_name")] =
theLoc_name.getValue("Descript")
rows = arcpy.UpdateCursor(thisLayerDataSource, ["Descript", "CTCERTCODE",
"CTCERTDESC", "SortMe"])
for row in rows:
thisLocName = row.getValue("Loc_name")
if ((thisLocName != ' ') and (thisLocName != '')):
thisDescript = theDescriptDict[thisLocName]
row.setValue("Descript", str(thisDescript))
If you have several fields in the second table, just make a dictionary for each field (still keyed by the same unique field) and using the UpdateCursor on the primary table, use row.setValue statements for each field.
Answered by JDMorganArkansas on March 2, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP