I have a script with several functions in it that use arcpy.ListFeatureClasses(). I'm having trouble pointing each function at the proper workspace. It seems like if I change the workspace inside a function then all the function calls after that use the wrong workspace. But if I set the arcpy.env.workspace inside each function it throws errors saying
''ERROR 000732: Input Table: filename does not exist or is not supported''
How do I point each function at its proper workspace? Images of a couple of the functions are below:
Why troubleshoot a problem with legacy ArcPy functions when you can use newer, better ArcPy functions. See Walk—ArcGIS Pro | Documentation
It's even easier these days with arcpy.EnvManager
with arcpy.EnvManager(workspace=r"D:\Data"): some_function()
It seems like if I change the workspace inside a function then all the function calls after that use the wrong workspace.
Yep. If you change the workspace, you need to change it back.
What I do is use a context manager to temporarily set arcpy.env values and then automatically reset them to the original values.
<SPAN class="keyword token">from</SPAN> contextlib <SPAN class="keyword token">import</SPAN> contextmanager <SPAN class="keyword token">import</SPAN> arcpy @contextmanager <SPAN class="keyword token">def</SPAN> <SPAN class="token function">env</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="operator token">**</SPAN>kwargs<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">""" context manager for arcpy.env vars """</SPAN> <SPAN class="keyword token">try</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="comment token"># Copy old env then set new values</SPAN> old_env <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">{</SPAN><SPAN class="punctuation token">}</SPAN> <SPAN class="keyword token">for</SPAN> key<SPAN class="punctuation token">,</SPAN> val <SPAN class="keyword token">in</SPAN> kwargs<SPAN class="punctuation token">.</SPAN>items<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> old_env<SPAN class="punctuation token">[</SPAN>key<SPAN class="punctuation token">]</SPAN> <SPAN class="operator token">=</SPAN> getattr<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>env<SPAN class="punctuation token">,</SPAN> key<SPAN class="punctuation token">)</SPAN> setattr<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>env<SPAN class="punctuation token">,</SPAN> key<SPAN class="punctuation token">,</SPAN> val<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">yield</SPAN> <SPAN class="keyword token">finally</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="comment token"># Restore old values</SPAN> <SPAN class="keyword token">for</SPAN> key<SPAN class="punctuation token">,</SPAN> val <SPAN class="keyword token">in</SPAN> old_env<SPAN class="punctuation token">.</SPAN>items<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> setattr<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>env<SPAN class="punctuation token">,</SPAN> key<SPAN class="punctuation token">,</SPAN> val<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">def</SPAN> <SPAN class="token function">some_function</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">print</SPAN><SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>env<SPAN class="punctuation token">.</SPAN>workspace<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">if</SPAN> __name__ <SPAN class="operator token">==</SPAN> <SPAN class="string token">'__main__'</SPAN><SPAN class="punctuation token">:</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>env<SPAN class="punctuation token">.</SPAN>workspace <SPAN class="operator token">=</SPAN> <SPAN class="string token">'C:/Temp'</SPAN> some_function<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">with</SPAN> env<SPAN class="punctuation token">(</SPAN>workspace<SPAN class="operator token">=</SPAN><SPAN class="string token">'D:/GIS'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> some_function<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> some_function<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">with</SPAN> env<SPAN class="punctuation token">(</SPAN>workspace<SPAN class="operator token">=</SPAN><SPAN class="string token">'G:/Work'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> some_function<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> some_function<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
This outputs:
C:/temp D:/GIS C:/temp G:/Work C:/temp<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Shoot.... You lost me at QGIS ... 😉
I guess you may want to go back and reset PYTHONPATH and PATH and start over?
Thanks for the tips Joe! After some testing today I've come to the conclusion that I am having issues with the environment Spyder is set up in. I was messing with the PYTHONPATH and PATH last week to try and work with QGIS tools as well and now I'm getting unexpected behavior from Spyder IDE, which is installed in the cloned environment. My functions run great in IDLE and the ArcGIS Pro python window but not in Spyder.
It sure is fun stuff to try and figure out /s. I re-cloned my environment and downloaded spyder into that but I am still getting the same error. Not sure what my next move is.
James- Along with what @Randy_Burton suggests, using
<SPAN class="keyword token">import</SPAN> arcpy arcpy<SPAN class="punctuation token">.</SPAN>env<SPAN class="punctuation token">.</SPAN>workspace <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'X\some\path\to\your.gdb'</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN></SPAN>
sets it explicitly. With ListFeatureClasses and ListTables() both need the workspace set as shown above, and I don't think either of them take an argument. If you are going to set a workspace with env and copy data to a different out workspace, just set a variable:
arcpy.env.workspace = r'T:\GIS Documents\MOW\SDE_Surrogate.gdb' outWS = r'T:\GIS Documents\MOW\ClientCount.gdb' fields = ['Month','Year'] arcpy.SplitByAttributes_analysis('MasterDelivery2018',outWS,fields)<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Notice how line one sets the env while line 2 sets where I want the output of SplitByAttributes() to go.
Another example:
arcpy<SPAN class="punctuation token">.</SPAN>env<SPAN class="punctuation token">.</SPAN>workspace <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'T:\GIS Documents\MOW\ClientCountSum2.gdb'</SPAN> outWS <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>env<SPAN class="punctuation token">.</SPAN>workspace inFeatures <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'I:\GIS\ArcSDE\SuperUser\is\slco@slcopub.sde\slcopub.SLCO.Administration\slcopub.SLCO.ZipCodes'</SPAN> layerName <SPAN class="operator token">=</SPAN> <SPAN class="string token">'zipLayer'</SPAN> joinField1 <SPAN class="operator token">=</SPAN> <SPAN class="string token">'ZIP_CD'</SPAN> joinfield2 <SPAN class="operator token">=</SPAN> <SPAN class="string token">'FIRST_Residential_Zipcode'</SPAN> <SPAN class="keyword token">for</SPAN> t <SPAN class="keyword token">in</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>ListTables<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">try</SPAN><SPAN class="punctuation token">:</SPAN> joinTable <SPAN class="operator token">=</SPAN> t outFeature <SPAN class="operator token">=</SPAN> <SPAN class="string token">'{}\{}joined'</SPAN><SPAN class="punctuation token">.</SPAN>format<SPAN class="punctuation token">(</SPAN>outWS<SPAN class="punctuation token">,</SPAN>t<SPAN class="punctuation token">)</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>MakeFeatureLayer_management <SPAN class="punctuation token">(</SPAN>inFeatures<SPAN class="punctuation token">,</SPAN> layerName<SPAN class="punctuation token">)</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>AddJoin_management<SPAN class="punctuation token">(</SPAN>layerName<SPAN class="punctuation token">,</SPAN> joinField1<SPAN class="punctuation token">,</SPAN> joinTable<SPAN class="punctuation token">,</SPAN> joinfield2<SPAN class="punctuation token">)</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>CopyFeatures_management<SPAN class="punctuation token">(</SPAN>layerName<SPAN class="punctuation token">,</SPAN> outFeature<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">print</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">'Success: created month feature class'</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">except</SPAN> Exception <SPAN class="keyword token">as</SPAN> err<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">print</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">'Error'</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">print</SPAN><SPAN class="punctuation token">(</SPAN>err<SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Line 2 sets the outWS explicitly so I can use it a little later in line 11 where I name the out feature class using the original table name with the word 'joined' pasted to the end of it.
and finally, one more example I just wrote for the same meals on wheels project I working on:
arcpy<SPAN class="punctuation token">.</SPAN>env<SPAN class="punctuation token">.</SPAN>workspace <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'T:\GIS Documents\MOW\ClientCountSum2.gdb'</SPAN> target <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'T:\GIS Documents\MOW\SDE_Surrogate.gdb\ClientCountByZip'</SPAN> <SPAN class="keyword token">for</SPAN> x <SPAN class="keyword token">in</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>ListFeatureClasses<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Append_management<SPAN class="punctuation token">(</SPAN>x<SPAN class="punctuation token">,</SPAN>target<SPAN class="punctuation token">,</SPAN><SPAN class="string token">'NO_TEST'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Glad to see you are writing python at your new job!
After a quick look at your functions, you might set and then pass the workspace to your function:
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">someFunction</SPAN><SPAN class="punctuation token">(</SPAN>ws<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> workspace <SPAN class="operator token">=</SPAN> ws <SPAN class="comment token"># more code</SPAN> <SPAN class="keyword token">return</SPAN> something workspace1 <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'C:\Some\Path\to\data1.gdb'</SPAN> x <SPAN class="operator token">=</SPAN> someFunction<SPAN class="punctuation token">(</SPAN>workspace1<SPAN class="punctuation token">)</SPAN> workspace2 <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'C:\Some\Path\to\data2.gdb'</SPAN> y <SPAN class="operator token">=</SPAN> someFunction<SPAN class="punctuation token">(</SPAN>workspace2<SPAN class="punctuation token">)</SPAN> <SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Is this what you are looking for?
Do you know anything about functions and workspacesJoe Borgione?
Les membres connectés peuvent publier, suivre les mises à jour, et plus encore. Nouveau ici ? Inscrivez-vous gratuitement.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.