Skip to content

Cursor

Cursor Helper module

CLASS DESCRIPTION
Field

Field Representation

InsertOptions

Optional parameters for InsertCursors

SQLClause

Wrapper for Cursor sql_clause attribute,

SearchOptions

Optional parameters for SearchCursors

UpdateOptions

Optional parameters for UpdateCursors

WhereClause

Wraps a string clause to signal to FeatureClass/Table indexes that a Where Clause is being passed

FUNCTION DESCRIPTION
convert_field

Convert an arcpy Field object to a Field argument dictionary

get_field_type

Convert a field type flag from a describe arcpy.Field to arguments for AddField

Field

Bases: TypedDict

Field Representation

ATTRIBUTE DESCRIPTION
field_type

The type of the field (required)

TYPE: FieldType

field_precision

The precision (digits) of numeric fields (default: database determined)

TYPE: int

field_scale

The number of decimal places for floating point fields (default: database determined)

TYPE: int

field_length

The maximum character count for TEXT fields (default: 255)

TYPE: int

field_alias

Human readable alias for fields with confusing internal names (optional)

TYPE: str

field_is_nullable

Allow null values (default: True)

TYPE: bool

field_is_required

Field requires a value to be set (default: False)

TYPE: bool

field_domain

Existing Domain name to bind to field (optional)

TYPE: str

InsertOptions

Bases: TypedDict

Optional parameters for InsertCursors

SQLClause

Bases: NamedTuple

Wrapper for Cursor sql_clause attribute,

ATTRIBUTE DESCRIPTION
prefix

The SQL prefix to be prepended to the FROM part of the statment

TYPE: str

postfix

The SQL postfix that will be appended to the WHERE clause

TYPE: str

Format
SELECT {prefix} {fields} FROM {table} WHERE {where_clause} {postfix}
Usage
>>> five_longest = SQLClause(prefix='TOP 5', postfix='ORDER BY LENGTH DESC')
>>> fc_result = feature_class.get_tuples(('NAME', 'LENGTH'), sql_clause=five_longest))
>>> print(list(fc_result))
[('foo', 1001), ('bar', 999), ('baz', 567), ('buzz', 345), ('bang', 233)]

SearchOptions

Bases: TypedDict

Optional parameters for SearchCursors

ATTRIBUTE DESCRIPTION
where_clause

A SQL query that is inserted after the SQL WHERE (SELECT {prefix} {fields} FROM {table} WHERE {where_clause} {postfix}...)

TYPE: str

spatial_reference

Perform an on the fly projection of the yielded geometry to this reference

TYPE: str | int | SpatialReference

explode_to_points

Return a row per vertex in each feature (e.g. [SHAPE, 'eric', 'idle'] -> [Point, 'eric', 'idle'], [Point, 'eric', 'idle'], ...)

TYPE: bool

sql_clause

A tuple of SQL queries that is inserted after the SQL SELECT and WHERE clauses (SELECT {prefix} {fields} FROM {table} WHERE {where_clause} {postfix}...)

TYPE: SQLClause

datum_transformation

The transformation to use during projection if there is a datum difference between the feature projection and the target SpatialReference (you can use arcpy.ListTransformations to find valid transformations)

TYPE: str

spatial_filter

A shape that will be used to test each feature against using the specified spatial_relationship ('INTERSECTS') by default.

TYPE: Geometry

spatial_relationship

The type of relationship with the spatial_filter to test for in each row. Only rows with shapes that match this relationship will be yielded.

TYPE: SpatialRelationship

search_order

Run the where_clause {sql_clause} ('ATTRIBUTEFIRST' default) or spatial_filter ('SPATIALFIRST') first. This can be used to optimize a cursor. If you have a complex where_clause, consider switching to 'SPATIALFIRST' to cut down on the number of records that the where_clause runs for. These two operations are done as seperate SQL operations and JOINED in the result

TYPE: SearchOrder

RETURNS DESCRIPTION
dict

A dictionary with the populated keys

Usage
>>> options = SearchOptions(where_clause='OBJECTID > 10')
>>> not_first_ten = feature_class.get_tuples(['NAME', 'LENGTH'], **options)
>>> print(list(not_first_ten))
[('cleese', 777), ('idle', 222), ('gilliam', 111), ...]

WhereClause

WhereClause(
    where_clause: str, skip_validation: bool = False
)

Wraps a string clause to signal to FeatureClass/Table indexes that a Where Clause is being passed

Object for storing and validating where clauses

PARAMETER DESCRIPTION

where_clause

The where clause that you want to pass to a FeatureClass

TYPE: str

skip_validation

Skip the validation step (default: False)

TYPE: bool DEFAULT: False

METHOD DESCRIPTION
get_fields

Sanitize a where clause by removing whitespace

validate

Check to see if the clause fields are in the fields list

Source code in src/arcpie/cursor.py
81
82
83
84
85
86
87
88
89
90
91
92
93
94
def __init__(self, where_clause: str, skip_validation: bool=False) -> None:
    """Object for storing and validating where clauses

    Args:
        where_clause (str): The where clause that you want to pass to a FeatureClass
        skip_validation (bool): Skip the validation step (default: False)
    """
    if '@' in where_clause:
        raise AttributeError(
            '`@` Parameters/Tokens not supported in WhereClauses, Please use full fieldname'
        )
    self.where_clause = where_clause
    self.fields = self.get_fields(where_clause)
    self.skip_validation = skip_validation

get_fields

get_fields(clause: str) -> Sequence[str]

Sanitize a where clause by removing whitespace

Source code in src/arcpie/cursor.py
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
def get_fields(self, clause: str) -> Sequence[str]:
    """Sanitize a where clause by removing whitespace"""

    #    -0-     1    2      3      -4-      5    6
    # '<FIELD> <OP> <VAL> <AND/OR> <FIELD> <OP> <VAL> ...'
    # A properly structured WhereClause should have a field
    # as every 4th token split on spaces

    # CAVEAT: Parens and whitespace
    # This comprehension drops individual parens, replaces ', ' with ','
    # and finds all field components

    # TODO: This needs thorough testing
    return [
        fld.strip().replace('(', '').replace(')', '')
        for fld in [
            tok for tok in
            clause.replace(', ', ',').split()
            if tok not in '()'
        ][::4]
    ]

validate

validate(fields: Sequence[str]) -> bool

Check to see if the clause fields are in the fields list

PARAMETER DESCRIPTION

fields

The fields to check against

TYPE: Sequence[str]

Source code in src/arcpie/cursor.py
121
122
123
124
125
126
127
def validate(self, fields: Sequence[str]) -> bool:
    """Check to see if the clause fields are in the fields list

    Args:
        fields (Sequence[str]): The fields to check against
    """
    return self.skip_validation or set(self.fields) <= set(fields)

convert_field

convert_field(arc_field: Field) -> Field

Convert an arcpy Field object to a Field argument dictionary

PARAMETER DESCRIPTION

arc_field

The Field object returned by Describe().fields

TYPE: Field

RETURNS DESCRIPTION
Field

A Field argument dictionary that can be used to construct a new field

Source code in src/arcpie/cursor.py
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
def convert_field(arc_field: ArcField) -> Field:
    """Convert an arcpy Field object to a Field argument dictionary

    Args:
        arc_field (arcpy.Field): The Field object returned by Describe().fields

    Returns:
        (Field): A Field argument dictionary that can be used to construct a new field
    """
    return Field(
        field_type=get_field_type(arc_field.type),
        field_precision=arc_field.precision,
        field_scale=arc_field.scale,
        field_length=arc_field.length,
        field_alias=arc_field.aliasName,
        field_is_nullable='NULLABLE' if arc_field.isNullable else 'NON_NULLABLE',
        field_is_required='REQUIRED' if arc_field.required else 'NON_REQUIRED',
        field_domain=arc_field.domain,
        field_default=arc_field.defaultValue,
    )

get_field_type

get_field_type(
    arc_field_type: FieldType, *, strict: bool = False
) -> FieldType

Convert a field type flag from a describe arcpy.Field to arguments for AddField

PARAMETER DESCRIPTION

arc_field_type

The field type as reported by arcpy.Describe(...).fields

TYPE: FieldType

strict

Raise a ValueError if this is set to True, otherwise assume TEXT

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
FieldType

(FieldType)

RAISES DESCRIPTION
ValueError

If strict flag is set and the input type is unmapped

Source code in src/arcpie/cursor.py
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
def get_field_type(arc_field_type: ArcFieldType, *, strict: bool=False) -> FieldType:
    """Convert a field type flag from a describe arcpy.Field to arguments for AddField

    Args:
        arc_field_type (ArcFieldType): The field type as reported by arcpy.Describe(...).fields
        strict (bool): Raise a ValueError if this is set to True, otherwise assume `TEXT`

    Returns:
        (FieldType)

    Raises:
        (ValueError): If `strict` flag is set and the input type is unmapped
    """
    match arc_field_type:
        case 'BigInteger':
            return 'BIGINTEGER'
        case 'Blob':
            return 'BLOB'
        case 'Date':
            return 'DATE'
        case 'DateOnly':
            return 'DATEONLY'
        case 'Double':
            return 'DOUBLE'
        case 'Geometry': # No Passthrough
            return 'BLOB'
        case 'GlobalID': # No Passthrough
            return 'GUID'
        case 'GUID':
            return 'GUID'
        case 'Integer':
            return 'LONG'
        case 'OID':
            return 'BIGINTEGER'
        case 'Raster':
            return 'RASTER'
        case 'Single':
            return 'FLOAT'
        case 'SmallInteger':
            return 'SHORT'
        case 'String':
            return 'TEXT'
        case 'TimeOnly':
            return 'TIMEONLY'
        case 'TimestampOffset':
            return 'TIMESTAMPOFFSET'
        case _:
            if strict:
                raise ValueError()
            return 'TEXT'