3

I have a dynamic list of ObjectID values I need to filter an UpdateCursor on. I am setting a where_clause as:

where_clause_points = "[ObjectID] IN({0})".format([x for x in inspected_points])

Which produces a string something like:

[ObjectID] IN([87, 88, 89, 90])

I then use this where clause in an UpdateCursor to update only the features in that list of ObjectID's:

with arcpy.da.UpdateCursor(lines_backup, fields, where_clause_points) as cursor:
 for row in cursor:
 row[1] = 'processed'
 cursor.updateRow(row)

But this produces the error:

...RuntimeError: Attribute column not found [42S22:[Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Invalid column name '87, 88, 89, 90, 91, 92'.]...

or if using some other value for ObjectID:

RuntimeError: Attribute column not found [42S22:[Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Invalid column name 'OID'.]

Any sort of value I use for ObjectID (OBJECTID, OID, OID@, etc.) throws a similar error.

How can I reference the ObjectID in this where clause where the value is variable and in a list of possible values?

Environment: Python 3.6.5 (stand alone script) ArcGIS 10.6 Microsoft SQL Server db

Vince
20.5k16 gold badges49 silver badges65 bronze badges
asked Jan 17, 2019 at 4:42
2
  • "ObjectID IN({0})".format(','.join([x for x in inspected_points])) is more SQL correct, this will expand to ObjectID IN (87, 88, 89, 90) which is correct SQL syntax for numbers. the square brackets are not needed in the in list, neither for the field name in a select statement - using field delimiters limits portability to other feature types for no benefit in selection. Note that you can get your OID field name from describing your feature class: arcpy.Describe(fc).OIDFieldName Commented Jan 17, 2019 at 5:32
  • 1
    @MichaelStimson that worked! I did have to convert the x to str(x) but that did output a query string of "ObjectID IN(87, 88, ...) and seemed to work as desired. Thanks! I'll also try Bera's suggestion as well, as there may be variance in the naming of that field in different environments/dbs... Commented Jan 17, 2019 at 15:50

1 Answer 1

4

Depending on input source, the objectid field will have different names. You can use Describe to get the correct name, and the code will work with all different inputs.

Combine this with the tuple data type to get correct SQL syntax, [1,2,3] to (1,2,3).

"features" is a feature layer:

ids = [1,2,3,4,5]
tuple(ids)
(1, 2, 3, 4, 5)
oidfield = arcpy.Describe("features").OIDFieldName
oidfield
u'OBJECTID'
sql = "{0} IN{1}".format(arcpy.AddFieldDelimiters("features",oidfield),tuple(ids))
sql
'"OBJECTID" IN(1, 2, 3, 4, 5)'
with arcpy.da.UpdateCursor("features", ["somefield1","somefield2"], sql) as cursor:
 ...
answered Jan 17, 2019 at 6:03
2
  • 1
    that worked as well! I'm not fully understanding the syntax you used, mainly the triple quoting the sql string portion, but do see how you made the list of possible, and unknown length, values into a format acceptable to the IN statement along with the proper OID format coming from the esri delimiter. Nice! Commented Jan 17, 2019 at 16:00
  • @m.Walker nice! I dont think it makes any difference with three quotes or one. Commented Jan 18, 2019 at 9:47

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.