Checking if field is unique value field

3843
22
Jump to solution
10-16-2017 01:27 PM
JohnDye
Occasional Contributor III

I have a parameter in a python toolbox which allows a user to select a field from a dataset given in a previous parameter.

# Feature Class to absorb geometry from
param2 = arcpy.Parameter(
    displayName="Geometry Feature Class",
    name="in_geoFC",
    datatype="GPFeatureLayer",
    parameterType="Required",
    direction="Input")‍‍‍‍‍‍‍

# Table ID field
param3 = arcpy.Parameter(
    displayName="Table Geometry ID Field",
    name="table_geoIDField",
    datatype="GPString",
    parameterType="Required",
    direction="Input",
    enabled=False)
param3.filter.type = "ValueList"
param3.filter.list = []‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The updateParameters section contains logic to update Parameter 3 with the field names for all of the fields in the dataset provided in parameter 2 which have a datatype of string:

def updateParameters(self, parameters):
    """Modify the values and properties of parameters before internal
       validation is performed.  This method is called whenever a parameter
       has been changed."""
    
    # if 'in_geoFC' is populated with a value
    if parameters[2].value:
        # if 'in_geoFC' does not have an error set
        if not parameters[2].hasError():
            #  Create a list of all of the fields in the 'in_geoFC'
            # which have a datatype of 'String'
            fc_geoIDFields = [field.name for field in arcpy.Describe(
                              parameters[2].valueAsText).fields
                              if field.type == 'String']
            # Enable the parameter
            parameters[3].enabled = True
            # Populate the parameter with the list of text fields in the
            # table
            parameters[3].filter.list = fc_geoIDFields‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

This all works just fine...

There's one more thing I need to do though. Whichever field the user selects for parameter 3, I need to ensure that the values contained in this field are unique - every record must have a unique value.

I know of a pretty easy and elegant way to get the number of unique values in that field:

len(set(r[0] for r in arpy.da.SearchCursor(parameters[1].valueAsText
                                           , parameters[2].valueAsText)))‍‍‍‍‍‍

What I don't know is the quickest and most elegant way to get the total number of features in that dataset so that I can compare it to the number of unique values in that field and thus, determine if all of the values in that field are unique.

Keep in mind that this would be occurring in the updateMessages function, so it needs to be a fairly quick process.

Any thoughts on how to get a record count super fast?

0 Kudos
22 Replies
JamesCrandall
MVP Frequent Contributor

Is this an SDE feature class?  If so, have you tried a standard SQL count statement against the RBMS?

0 Kudos
JohnDye
Occasional Contributor III

That could be an option. I'm not sure how it would perform though given that our internal network is absolute garbage.

In any case, once I implemented the custom function I had defined in the updateMessages section of my toolbox - for some reason that is not clear to me, the result is almost instantaneous. Must faster than the 6 seconds I was getting back when running this in the Python Window. 

Pretty much every answer on this post is correct though. Which one to mark correct? I suppose I'll defer to the Dan the Man ( Dan Patterson‌ ) to pick the best answer.

On a side note - why would a Python Toolbox be able to run that function so much faster than the Python Window? I get that Python Toolboxes can be background enabled (which this one is), allowing them to run in a separate, 64-bit thread - but the performance difference is so dramatic (I seriously mean that the error is raised within 1 second) that I feel like there has to be something else going on that I just don't know about.

0 Kudos
DanPatterson_Retired
MVP Emeritus

Your call on answer or useful...

As for speed, if python toolbox functionality isn't needed, why use them? Conventional toolboxes are simple and clean and I like the fact that the 'human' interface actually has to think about what they are doing, instead of writing tools that account for all issues between the keyboard and the chair

0 Kudos