Tutorial: Create data

Learn how to add, update, and delete features in a hosted feature layer.

Get local data

In this tutorial you will use the Point, Feature, and FeatureLayer classes to create new features in an existing feature layer. The data will be stored in your own ArcGIS Portal and can be used in other tutorials and projects.

Prerequisites

The ArcGIS API for Python tutorials use Jupyter Notebooks to execute Python code. If you are new to this environment, please see the guide to install the API and use notebooks locally.

Steps

Prepare data

  1. You will access the Trailheads feature layer created in the Import data tutorial. You can also create a blank online layer using your portal, see the Define a new feature layer tutorial for detailed steps.

Import modules and log in

  1. Import GIS from the arcgis.gis module and use it to log in to your portal using an ArcGIS Location Platform account, ArcGIS Online account, or ArcGIS Enterprise account.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    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
    
    from arcgis.gis import GIS
    from arcgis.geometry import Point
    from arcgis.features import Feature
    import random
    
    portal = GIS(username="username")
    print(f"connected to {portal.properties.name} as {portal.properties.user.username}")
    
    

Access the feature layer

  1. Use the content property to search for the Trailheads feature service you created in the Import Data tutorial.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    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
    
    from arcgis.gis import GIS
    from arcgis.geometry import Point
    from arcgis.features import Feature
    import random
    
    portal = GIS(username="username")
    print(f"connected to {portal.properties.name} as {portal.properties.user.username}")
    
    query = 'title: "Trailheads*" AND type: "Feature Service"'
    search_results = gis.content.search(query=query, max_items=10)
    
    
  2. Find the Trailheads feature service from the list of results, and display the URL of the item. The index for the specific layer may be different in your organization.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    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
    
    query = 'title: "Trailheads*" AND type: "Feature Service"'
    search_results = gis.content.search(query=query, max_items=10)
    
    trailheads_item = search_results[0]
    trailheads_item.url
    
    
  3. Access the list of layers in the feature service, and assign the trailheads feature layer to a new variable named points_layer.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    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
    
    query = 'title: "Trailheads*" AND type: "Feature Service"'
    search_results = gis.content.search(query=query, max_items=10)
    
    trailheads_item = search_results[0]
    trailheads_item.url
    
    points_layer = trailheads_item.layers[0]
    points_layer.properties.name
    
    
  4. List the field names and field types by enumerating through the fields using the layer properties. This will give us insight into which fields we want to use when editing.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    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
    
    trailheads_item = search_results[0]
    trailheads_item.url
    
    points_layer = trailheads_item.layers[0]
    points_layer.properties.name
    
    for field in points_layer.properties['fields']:
      print(f"Name: {field['name']}, type: {field['type']}")
    
    
  5. Call the query method using the return_count_only parameter to return the current number of features contained in the feature layer.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    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
    
    trailheads_item = search_results[0]
    trailheads_item.url
    
    points_layer = trailheads_item.layers[0]
    points_layer.properties.name
    
    for field in points_layer.properties['fields']:
      print(f"Name: {field['name']}, type: {field['type']}")
    
    current_feature_count = points_layer.query(where="1=1", return_count_only=True)
    current_feature_count
    
    

Create an edit function

  1. Write a reusable function that returns feature objects given an input point geometry. You will use the geometry module to create a Point geometry object and the features module to create a Feature object. Use the random module to generate values to use as values for attributes. Use field names we discovered back in step 6.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    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
    
    for field in points_layer.properties['fields']:
      print(f"Name: {field['name']}, type: {field['type']}")
    
    current_feature_count = points_layer.query(where="1=1", return_count_only=True)
    current_feature_count
    
    def create_feature(from_point):
        # create a psuedo random number
        random_num = random.sample(range(-32678, 32767), 1)[0]
        # create a new point geometry
        point = Point({
            "x": from_point[0],
            "y": from_point[1],
            "spatialReference": {"wkid": 102100}
        })
        # create a new feature object
        new_feature = Feature(
            geometry=point,
            attributes={
                "TRL_ID": random_num,
                "TRL_NAME": f"Trail {random_num}"
            })
        # return the new feature
        return new_feature
    
    

Perform the edit operations

  1. Create a list of point geometries to be added to the feature layer.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    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
    
    def create_feature(from_point):
        # create a psuedo random number
        random_num = random.sample(range(-32678, 32767), 1)[0]
        # create a new point geometry
        point = Point({
            "x": from_point[0],
            "y": from_point[1],
            "spatialReference": {"wkid": 102100}
        })
        # create a new feature object
        new_feature = Feature(
            geometry=point,
            attributes={
                "TRL_ID": random_num,
                "TRL_NAME": f"Trail {random_num}"
            })
        # return the new feature
        return new_feature
    
    # create a list of points to add to the feature layer
    pts = [
        [-13171333.070799998939037, 4042695.321999996900558],
        [-13242990.358199998736382, 4033735.280599996447563],
        [-13175934.033300001174212, 4019713.409100003540516],
        [-13205283.364500001072884, 4024074.358800001442432],
        [-13240366.94880000129342, 4038035.472000002861023],
        [-13262797.765900000929832, 4042863.907899998128414],
        [-13225526.658399999141693, 4047097.181400001049042],
        [-13198009.883299998939037, 4034317.139899998903275],
        [-13173824.26300000026822, 4018733.889600001275539],
        [-13219729.814500000327826, 4024812.550099998712540],
        [-13168754.60139999911189, 4042368.257200002670288],
        [-13186098.097899999469519, 4031719.417900003492832],
        [-13260383.321899998933077, 4043455.122699998319149],
        [-13204961.706000000238419, 4048183.480999998748302],
        [-13216203.758700000122190, 4059118.715800002217293],
        [-13263163.670600000768900, 4050992.630599997937679],
        [-13187563.843699999153614, 4051919.309100002050400],
        [-13264305.876699998974800, 4038344.382200002670288],
        [-13231383.650699999183416, 4050043.688400000333786],
        [-13216463.800000000745058, 4042839.030299998819828],
    ]
    
    
  2. Iterate through each geometry in the array and call the edit function. This will return a list new features.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    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
    
    # create a list of points to add to the feature layer
    pts = [
        [-13171333.070799998939037, 4042695.321999996900558],
        [-13242990.358199998736382, 4033735.280599996447563],
        [-13175934.033300001174212, 4019713.409100003540516],
        [-13205283.364500001072884, 4024074.358800001442432],
        [-13240366.94880000129342, 4038035.472000002861023],
        [-13262797.765900000929832, 4042863.907899998128414],
        [-13225526.658399999141693, 4047097.181400001049042],
        [-13198009.883299998939037, 4034317.139899998903275],
        [-13173824.26300000026822, 4018733.889600001275539],
        [-13219729.814500000327826, 4024812.550099998712540],
        [-13168754.60139999911189, 4042368.257200002670288],
        [-13186098.097899999469519, 4031719.417900003492832],
        [-13260383.321899998933077, 4043455.122699998319149],
        [-13204961.706000000238419, 4048183.480999998748302],
        [-13216203.758700000122190, 4059118.715800002217293],
        [-13263163.670600000768900, 4050992.630599997937679],
        [-13187563.843699999153614, 4051919.309100002050400],
        [-13264305.876699998974800, 4038344.382200002670288],
        [-13231383.650699999183416, 4050043.688400000333786],
        [-13216463.800000000745058, 4042839.030299998819828],
    ]
    
    # iterage through each coordinate in the array and return a list of new features
    new_features = []
    for pt in pts:
        new_features.append(create_feature(pt))
    print(f"{len(new_features)} new feature objects generated")
    
    
  3. Use the edit_features method to send the list of new features to the feature layer. Then perform another count of features in the feature layer again. The count should increase by twenty.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    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
    
    # iterage through each coordinate in the array and return a list of new features
    new_features = []
    for pt in pts:
        new_features.append(create_feature(pt))
    print(f"{len(new_features)} new feature objects generated")
    
    # Use the `edit_features` method to send our list of new feature objects to the feature layer
    edit_result = points_layer.edit_features(adds=new_features) # for a large number of features it is recommended to use the [append]() method.
    edit_result
    
    post_add_feature_count = points_layer.query(where="1=1", return_count_only = True)
    print(f"post add features count: {post_add_feature_count}")
    
    
  4. Update an attribute of the features you just created. The add operation will return a result object containing the list of objectIds that were successfully updated. Loop through the add results and create an array of attribute objects with a new value and the OBJECTID. Use the edit_features again method but use the updates parameter and pass in our list of attribute values.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    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
    
    # Use the `edit_features` method to send our list of new feature objects to the feature layer
    edit_result = points_layer.edit_features(adds=new_features) # for a large number of features it is recommended to use the [append]() method.
    edit_result
    
    post_add_feature_count = points_layer.query(where="1=1", return_count_only = True)
    print(f"post add features count: {post_add_feature_count}")
    
    # get the objectid field name from our source layer
    oid_fld = points_layer.properties.objectIdField
    update_features = []
    for itm in edit_result['addResults']:
        update_features.append({
            "attributes":{
                oid_fld:int(itm['objectId']), # update requires an objectid
                "FEAT_CMNT": "Delete Me" # update an existing field value
            }
        })
    update_features
    
    points_layer.edit_features(updates = update_features)
    
    
  5. Delete features from the feature layer. Use the query method to retrieve the features that were just added as a FeatureSet (as_df=false). Pass these features to the edit_features method, in the deletes parameter. Perform another count, the final count (post_delete_feature_count) should equal the current_feature_count.

    Use dark colors for code blocks
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    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
    
    # get the objectid field name from our source layer
    oid_fld = points_layer.properties.objectIdField
    update_features = []
    for itm in edit_result['addResults']:
        update_features.append({
            "attributes":{
                oid_fld:int(itm['objectId']), # update requires an objectid
                "FEAT_CMNT": "Delete Me" # update an existing field value
            }
        })
    update_features
    
    points_layer.edit_features(updates = update_features)
    
    remove_points = points_layer.query(where="FEAT_CMNT = 'Delete Me'", out_fields="*", as_df=False)
    points_layer.edit_features(deletes = remove_points)
    
    post_delete_feature_count = points_layer.query(where="1=1", return_count_only = True)
    print(f"post delete feature count: {post_delete_feature_count}")
    
    print(f"Start and end counts are equal: {current_feature_count == post_delete_feature_count}")

What's next?

Learn how to use additional functionality in these tutorials:

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.