Is it possible to use MakeFeatureLayer_management out of process?

635
7
04-08-2020 08:48 AM
DamianKolbay
New Contributor II

Hello all and thanks in advance for reading through my question,

I'm writing a python script that is selecting features from a GDB feature class and using the attributes from the selected features during my analysis.  I'm eventually displaying a Tkinter form to the user that displays the results.  My script works fine if I run it outside of ArcMap in a command prompt but if I run it inside as a script tool (out of process) it fails. 

I have worked through launching a script from a toolbox and running it "out of process" (unchecked Run Python script in process) to display the Tkinter form.  As long as I don't need to use MakeFeatureLayer_management, my form launches, displays results, and behaves as expected.  But since I need to create a layer from the GDB feeature class to be able to select features, I am running into the problem.  The resultant layer from MakeFeatureLayer_management causes the script to fail if it is run out of process which is needed if I want to display a Tkinter form.  

The code below should be able to recreate the problem I am having.

  • Run it from the command line - prints the spatial reference name twice
  • Run from a script tool with "Run Python script in process" checked - outputs the spatial reference twice
  • Run from a script tool with "Run Python script in process" unchecked - crashes on line 8

import arcpy

myGDB = r'C:\Data\myGeoDatabase.gdb'
polyFeatureClass = ['Polys1', 'Polys2']

for i in range(0,len(polyFeatureClass)):
    polyLayer = arcpy.MakeFeatureLayer_management(myGDB + '\\' + polyFeatureClass[i], polyFeatureClass[i])
    sr = arcpy.Describe(polyLayer).spatialReference
    print(sr.name)
    arcpy.AddMessage(sr.name)

Any thoughts on what might be causing this and how I might be able to get around it?  Is there another method to select feature from the feature class?  I read what appeared to be a similar question posed in 2014 (https://community.esri.com/thread/104854) but the end solution was to run it outside of ArcMap.  I really want my users to be able to use the tool within ArcMap.

Thanks,

Damian

0 Kudos
7 Replies
JoeBorgione
MVP Emeritus

If you are going to run it in ArcMap, why bother with the Tkinter form; isn't that what a pyt or just a script tool is used for?  I've always heard the ArcGIS and Tkinter don't play nice nice with each other.  Also, are the layers you are working with part of the ArcMap mxd?  I'm a little confused with what your end game is here; stand alone outside of ArcGIS or as a tool within ArcGIS?

That should just about do it....
0 Kudos
DamianKolbay
New Contributor II

My goal is to allow a user to click on a map in ArcMap and display the results of the querying of many tables of a database based on the original feature that was clicked.  Basically, the user clicks a polygon, somewhere around 10 one to many database tables are queried and the results of the "tree" query are returned to the user in a format they are familiar with.  I can make the query without the Tkinter form, but displaying the results in an easy to understand format requires the nesting and merging of results into a display that I believe would be impossible to recreate without Tkinter or similar.

Yep, ArcGIS and Tkinter tend to disagree and cause problems; that's why the script has to be run out of process.  That way ArcMap and Tkinter don't interact.  The script starts a new python process, feeds it the parameters, and basically waits until the form is killed without ever communicating between the two processes.

0 Kudos
JoeBorgione
MVP Emeritus

Have you considered a Python Addin?

That should just about do it....
0 Kudos
DamianKolbay
New Contributor II

I actually run the tool as an Addin.  The Addin creates a custom tool on the toolbar.  The tool allows the user to click on the map and collects the X,Y of the click and feeds that as parameters to the script within a toolbox.  The script then starts the out of process python process that can launch the Tkinter form.  From what I have found, there is no way to tell an Addin directly to spawn a new process to run the Tkinter form although even there was, I'd be back to the same issue of the out of (arcmap) process need to use MakeFeatureLayer_management due to my reliance on Tkinter.  

0 Kudos
DavidPike
MVP Frequent Contributor
0 Kudos
DamianKolbay
New Contributor II

Thanks David but unfortunately the Visual C++ packages are on my machine so that wasn't the issue. 

0 Kudos
DamianKolbay
New Contributor II

I have not found a direct solution to fixing my problem, but I did find a work around that seems like it will be sufficient for now.  If I use the built in Python subprocess module to spawn a new Python process (instead of trying to run the script out of process through ArcMap) the script is happy to complete successfully in the new process.  I would have expected by unchecking "run in process" that ArcMap would have spawned a new process in the same manor as the subprocess module but somehow they are different.

The original makeFeauture script:

# Saved module as makeFeature.py
#------------------------------------------------------
import arcpy

myGDB = r'C:\Data\myGeoDatabase.gdb'
polyFeatureClass = ['Polys1', 'Polys2']

for i in range(0,len(polyFeatureClass)):
    polyLayer = arcpy.MakeFeatureLayer_management(myGDB + '\\' + polyFeatureClass[i], polyFeatureClass[i])
    sr = arcpy.Describe(polyLayer).spatialReference
    print(sr.name)
    arcpy.AddMessage(sr.name)
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

And now the subprocess script that launches the makeFeature.py script:

# saved as subprocess.py
#------------------------------------------
from subprocess import call
import sys
import os

pydir = sys.exec_prefix
pyexe = os.path.join(pydir, "python.exe")

call([pyexe,  'C:\\Data\\makeFeature.py'])‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The subprocess.py script can now be called directly from the Addin script instead of having to use a toolbox script without crashing.  I had to eventually configure the subprocess script to know where the makeFeature script is located so some path/file location handling is needed.  Not the best solution but one I believe I can deal with for now.