I have a parameter in a python toolbox which allows a user to select a field from a dataset given in a previous parameter.
<SPAN class="comment token"># Feature Class to absorb geometry from</SPAN>
param2 <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Parameter<SPAN class="punctuation token">(</SPAN>
displayName<SPAN class="operator token">=</SPAN><SPAN class="string token">"Geometry Feature Class"</SPAN><SPAN class="punctuation token">,</SPAN>
name<SPAN class="operator token">=</SPAN><SPAN class="string token">"in_geoFC"</SPAN><SPAN class="punctuation token">,</SPAN>
datatype<SPAN class="operator token">=</SPAN><SPAN class="string token">"GPFeatureLayer"</SPAN><SPAN class="punctuation token">,</SPAN>
parameterType<SPAN class="operator token">=</SPAN><SPAN class="string token">"Required"</SPAN><SPAN class="punctuation token">,</SPAN>
direction<SPAN class="operator token">=</SPAN><SPAN class="string token">"Input"</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="comment token"># Table ID field</SPAN>
param3 <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Parameter<SPAN class="punctuation token">(</SPAN>
displayName<SPAN class="operator token">=</SPAN><SPAN class="string token">"Table Geometry ID Field"</SPAN><SPAN class="punctuation token">,</SPAN>
name<SPAN class="operator token">=</SPAN><SPAN class="string token">"table_geoIDField"</SPAN><SPAN class="punctuation token">,</SPAN>
datatype<SPAN class="operator token">=</SPAN><SPAN class="string token">"GPString"</SPAN><SPAN class="punctuation token">,</SPAN>
parameterType<SPAN class="operator token">=</SPAN><SPAN class="string token">"Required"</SPAN><SPAN class="punctuation token">,</SPAN>
direction<SPAN class="operator token">=</SPAN><SPAN class="string token">"Input"</SPAN><SPAN class="punctuation token">,</SPAN>
enabled<SPAN class="operator token">=</SPAN><SPAN class="token boolean">False</SPAN><SPAN class="punctuation token">)</SPAN>
param3<SPAN class="punctuation token">.</SPAN>filter<SPAN class="punctuation token">.</SPAN>type <SPAN class="operator token">=</SPAN> <SPAN class="string token">"ValueList"</SPAN>
param3<SPAN class="punctuation token">.</SPAN>filter<SPAN class="punctuation token">.</SPAN>list <SPAN class="operator token">=</SPAN> <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>
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:
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">updateParameters</SPAN><SPAN class="punctuation token">(</SPAN>self<SPAN class="punctuation token">,</SPAN> parameters<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="string token">"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""</SPAN>
<SPAN class="comment token"># if 'in_geoFC' is populated with a value</SPAN>
<SPAN class="keyword token">if</SPAN> parameters<SPAN class="punctuation token">[</SPAN><SPAN class="number token">2</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>value<SPAN class="punctuation token">:</SPAN>
<SPAN class="comment token"># if 'in_geoFC' does not have an error set</SPAN>
<SPAN class="keyword token">if</SPAN> <SPAN class="operator token">not</SPAN> parameters<SPAN class="punctuation token">[</SPAN><SPAN class="number token">2</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>hasError<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN>
<SPAN class="comment token"># Create a list of all of the fields in the 'in_geoFC'</SPAN>
<SPAN class="comment token"># which have a datatype of 'String'</SPAN>
fc_geoIDFields <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN>field<SPAN class="punctuation token">.</SPAN>name <SPAN class="keyword token">for</SPAN> field <SPAN class="keyword token">in</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>Describe<SPAN class="punctuation token">(</SPAN>
parameters<SPAN class="punctuation token">[</SPAN><SPAN class="number token">2</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>valueAsText<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>fields
<SPAN class="keyword token">if</SPAN> field<SPAN class="punctuation token">.</SPAN>type <SPAN class="operator token">==</SPAN> <SPAN class="string token">'String'</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="comment token"># Enable the parameter</SPAN>
parameters<SPAN class="punctuation token">[</SPAN><SPAN class="number token">3</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>enabled <SPAN class="operator token">=</SPAN> <SPAN class="token boolean">True</SPAN>
<SPAN class="comment token"># Populate the parameter with the list of text fields in the</SPAN>
<SPAN class="comment token"># table</SPAN>
parameters<SPAN class="punctuation token">[</SPAN><SPAN class="number token">3</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>filter<SPAN class="punctuation token">.</SPAN>list <SPAN class="operator token">=</SPAN> fc_geoIDFields<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>
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<SPAN class="punctuation token">(</SPAN>set<SPAN class="punctuation token">(</SPAN>r<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">for</SPAN> r <SPAN class="keyword token">in</SPAN> arpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>parameters<SPAN class="punctuation token">[</SPAN><SPAN class="number token">1</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>valueAsText
<SPAN class="punctuation token">,</SPAN> parameters<SPAN class="punctuation token">[</SPAN><SPAN class="number token">2</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>valueAsText<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN></SPAN>
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?