Skip to content

cursor

Cursor Helper module

Field

Bases: TypedDict

Field Representation

Parameters:

Name Type Description Default
field_type FieldType

The type of the field (required)

required
field_precision int

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

required
field_scale int

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

required
field_length int

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

required
field_alias str

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

required
field_is_nullable bool

Allow null values (default: True)

required
field_is_required bool

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

required
field_domain str

Existing Domain name to bind to field (optional)

required
Source code in src/arcpie/cursor.py
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
class Field(TypedDict, total=False):
    """Field Representation

    Args:
        field_type (FieldType): The type of the field (required)
        field_precision (int): The precision (digits) of numeric fields (default: database determined)
        field_scale (int): The number of decimal places for floating point fields (default: database determined)
        field_length (int): The maximum character count for `TEXT` fields (default: 255)
        field_alias (str): Human readable alias for fields with confusing internal names (optional)
        field_is_nullable (bool): Allow null values (default: `True`)
        field_is_required (bool): Field requires a value to be set (default: False)
        field_domain (str): Existing Domain name to bind to field (optional)
    """
    field_type: FieldType
    field_precision: int
    field_scale: int
    field_length: int
    field_alias: str
    field_is_nullable: Literal['NULLABLE', 'NON_NULLABLE']
    field_is_required: Literal['REQUIRED']
    field_domain: bool

InsertOptions

Bases: TypedDict

Optional parameters for InsertCursors

Source code in src/arcpie/cursor.py
184
185
186
187
class InsertOptions(TypedDict, total=False):
    """Optional parameters for InsertCursors"""
    datum_transformation: str
    explicit: bool

SQLClause

Bases: NamedTuple

Wrapper for Cursor sql_clause attribute,

Parameters:

Name Type Description Default
prefix str

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

required
postfix str

The SQL postfix that will be appended to the WHERE clause

required
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)]
Source code in src/arcpie/cursor.py
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
class SQLClause(NamedTuple):
    """Wrapper for Cursor sql_clause attribute,

    Arguments:
        prefix (str): The SQL prefix to be prepended to the `FROM` part of the statment
        postfix (str): The SQL postfix that will be appended to the `WHERE` clause

    Format:
        ```sql
        SELECT {prefix} {fields} FROM {table} WHERE {where_clause} {postfix}
        ```

    Usage:
        ```python
        >>> 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)]
        ```
    """
    prefix: str|None
    postfix: str|None

SearchOptions

Bases: TypedDict

Optional parameters for SearchCursors

Parameters:

Name Type Description Default
where_clause str

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

required
spatial_reference str | int | SpatialReference

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

required
explode_to_points bool

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

required
sql_clause SQLClause

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

required
datum_transformation str

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)

required
spatial_filter Geometry

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

required
spatial_relationship SpatialRelationship

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.

required
search_order SearchOrder

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

required

Returns:

Type 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), ...]
Source code in src/arcpie/cursor.py
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
class SearchOptions(TypedDict, total=False):
    """Optional parameters for SearchCursors

    Arguments:
        where_clause (str): A SQL query that is inserted after the SQL `WHERE` (`SELECT {prefix} {fields} FROM {table} WHERE {where_clause} {postfix}...`)
        spatial_reference (str | int | SpatialReference): Perform an on the fly projection of the yielded geometry to this reference
        explode_to_points (bool): Return a row per vertex in each feature (e.g. `[SHAPE, 'eric', 'idle'] -> [Point, 'eric', 'idle'], [Point, 'eric', 'idle'], ...`)
        sql_clause (SQLClause): A tuple of SQL queries that is inserted after the SQL 
            `SELECT` and `WHERE` clauses (`SELECT {prefix} {fields} FROM {table} WHERE {where_clause} {postfix}...`)
        datum_transformation (str): 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)
        spatial_filter (Geometry): A shape that will be used to test each feature against using the specified `spatial_relationship` (`'INTERSECTS'`)
            by default.
        spatial_relationship (SpatialRelationship): 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.
        search_order (SearchOrder): 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

    Returns:
        ( dict ): A dictionary with the populated keys

    Usage:
        ```python
        >>> 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), ...]
        ```
    """
    where_clause: str
    spatial_reference: str | int | SpatialReference
    explode_to_points: bool
    sql_clause: SQLClause
    datum_transformation: str
    spatial_filter: GeometryType | Extent
    spatial_relationship: SpatialRelationship
    search_order: SearchOrder

UpdateOptions

Bases: TypedDict

Optional parameters for UpdateCursors

Source code in src/arcpie/cursor.py
189
190
191
192
193
194
195
196
197
198
199
200
201
class UpdateOptions(TypedDict, total=False):
    """Optional parameters for UpdateCursors"""
    where_clause: str
    spatial_reference: str | int | SpatialReference
    explode_to_points: bool
    sql_clause: SQLClause
    #skip_nulls: bool
    #null_value: dict[str, Any]
    datum_transformation: str
    explicit: bool
    spatial_filter: GeometryType | Extent
    spatial_relationship: SpatialRelationship
    search_order: SearchOrder

WhereClause

Source code in src/arcpie/cursor.py
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
class WhereClause:
    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

    def __repr__(self) -> str:
        return self.where_clause

    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]
        ]

    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)

__init__(where_clause, skip_validation=False)

Object for storing and validating where clauses

Parameters:

Name Type Description Default
where_clause str

The where clause that you want to pass to a FeatureClass

required
skip_validation bool

Skip the validation step (default: False)

False
Source code in src/arcpie/cursor.py
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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(clause)

Sanitize a where clause by removing whitespace

Source code in src/arcpie/cursor.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
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(fields)

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

Parameters:

Name Type Description Default
fields Sequence[str]

The fields to check against

required
Source code in src/arcpie/cursor.py
113
114
115
116
117
118
119
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)