A year or so ago I was working with Arcpy Addins. I had created an extension that used to run a def openDocument() that creates a numpy array out of a table view:
class ExtensionClass1(object):
"""Implementation for AddressValidatorExtension_addin.extension2 (Extension)"""
def __init__(self):
# For performance considerations, please remove all unused methods in this class.
self.enabled = True
def openDocument(self):
myTable = r"I:\GIS\ArcSDE\SuperUser\slcogis\gdb_ADD\gdb_ADD@slcogis.sde\SLCOGIS.gdb_ADD.JoesArray_vw"
fields = ['FULLNAME', 'LowCoordName', 'HighCoordName','Alias1','Alias2','Alias3','Alias4','STR2_LOW_RANGE','STR2_HIGH_RANGE']
global arr
arr = arcpy.da.TableToNumPyArray(myTable,fields)
The problem is when I try to execute the other functionalities of the extension it errors out at the first call to that array:
Traceback (most recent call last):
File "C:\Users\JBorgione\AppData\Local\ESRI\Desktop10.5\AssemblyCache\{FB53601C-244C-4DF3-87C2-E18F723FA707}\AddressValidatorExtension_addin.py", line 71, in onEnter
name = arr[np.where(arr['FULLNAME'] == enteredName)]
NameError: global name 'arr' is not defined
Not sure what I'm missing, and hoping another set of eyes can catch it
I don't like your path isn't the last bit supposed to be a table (but it is in SDEvil so I am not sure)
This works... but if you have any <null> values in your table, you have to skip them or go through some hoops. I have the hoop code if you need it. If you have nulls and don't provide null substitutes based on field types they you get an unfriendly error.
But that is for later.
def da_func():
from arcpy.da import TableToNumPyArray
myTable = r'C:/Git_Dan/arraytools/array_tools_testing/array_tools.gdb/pnts_2000'
fields = "*"
global arr
arr = TableToNumPyArray(myTable,fields, skip_nulls=True)
print(arr)
da_func()
[( 2, [ 303006., 5031740.], 1, 9.99, 650, 'B', 'e', 303006., 5031740., 3, 3., 'D4', 953, 34, 34)
( 4, [ 303987., 5026385.], 3, 11.57, 1605, 'D', 'b', 303987., 5026385., 1, 1., 'D9', 1620, 84, 84)
( 6, [ 309159., 5026073.], 5, 10.09, 521, 'B', 'c', 309159., 5026073., 8, 8., 'J9', 1272, 90, 90)
...
(1996, [ 307515., 5034669.], 1995, 11.75, 1759, 'D', 'b', 307515., 5034669., 4, 4., 'H1', 1875, 8, 8)
(1997, [ 300882., 5028630.], 1996, 10.82, 940, 'B', 'a', 300882., 5028630., 10, 10., 'A7', 565, 61, 61)
(1999, [ 305835., 5032342.], 1998, 10.33, 697, 'B', 'a', 305835., 5032342., 5, 5., 'F3', 1383, 26, 26)]
It's a table 'view' that is created on the SQL/SDEvil back end. I'll try the skip_nulls=True part on monday as I'm quite sure there are null alias# values. Maybe I need to apply arcpy.MakeTableView() to it; I'll try that as well. (The good news is this puts me back into the numpy thought process; the bad news is it's that addressing project from last year...)
Joe... in the first instance, set skillnulls to true or whatever. If there are any nulls in the fields you select, that row will be skipped
If you don't want rows that contain nulls skipped, I can provide you with the null dictionary that will provide acceptable null values so that the rows aren't skipped... it is a bit of an issue since <null> isn't 'None' in all cases, especially for integer fields etc.
If nulls isn't an issue, disregard everthing after Joe...
I can't afford to skip a row if one of the lesser-used fields has a null or empty value, so I need to take that into consideration. Just to get it up and running I can substitute a more ArcGIS friendly datasource (feature class or table and then make feature layer or make table view as needed) for the SQL view. We have the SQL view in place because (if you recall) the data is actually stored in a mainframe and we get a db dump from it and then SQL-view the dump. Big fun....
This is what I use sometimes. It needs field objects, just not their name (edit the code otherwise).
You can change what you want as the returned value. I normally just return the min for the data type. For string/text, just the string representation of text
def null_dict(flds):
"""Produce a null dictionary from a list of fields
These must be field objects and not just their name.
"""
dump_flds = ["OBJECTID","Shape_Length", "Shape_Area", "Shape"]
flds_oth = [f for f in flds
if f.name not in dump_flds]
nulls = {'Double':np.nan,
'Single':np.nan,
'Short':np.iinfo(np.int16).min,
'SmallInteger':np.iinfo(np.int16).min,
'Long':np.iinfo(np.int32).min,
'Float':np.nan,
'Integer':np.iinfo(np.int32).min,
'String':str(None),
'Text':str(None)}
fld_dict = {i.name: i.type for i in flds_oth}
nulls = {f.name:nulls[fld_dict[f.name]] for f in flds_oth}
return nulls
I'm thinking there is something wrong with the way I using the openDocument() method within the extension itself. I just took a took look at ArcMap Python Add In Extension does not execute where Darren Wiens provides a means to test. I created an extension that only does one thing: open a message box. However, with the extension added to an mxd, when I open that mxd, no message box appears....
##### this is the entire python script for my TestOnOpen extension...
import arcpy
import pythonaddins
class ExtensionClass1(object):
"""Implementation for TestOnOpen_addin.extension2 (Extension)"""
def __init__(self):
# For performance considerations, please remove all unused methods in this class.
self.enabled = True
def openDocument(self):
pythonaddins.MessageBox('It Ran!!!','INFO',0)