Select to view content in your preferred language

Is there a GP tool for inserting a row into a standalone table?

999
2
Jump to solution
01-16-2023 02:57 PM
Bud
by
Esteemed Contributor

Is there a geoprocessing tool for inserting a new row into a standalone table?

For example, in model builder, I want to add a new row to this non-spatial table:

Bud_0-1673909753758.png

ArcGIS Pro 3.0.3

Thanks.

1 Solution

Accepted Solutions
JohannesLindner
MVP Frequent Contributor

As Dan said, there's no out of the box tool. If you need that functionality in Model Builder, you have to create that tool yourself.

Below are two quick examples. You can save that script as a Python toolbox (.pyt), load that into ArcGIS Pro, and then drag the tools in to your model.

# -*- coding: cp1252 -*-

import arcpy


class Toolbox(object):
    def __init__(self):
        self.label = "Utility"
        self.alias = "utility"
        self.tools = [InsertRow, InsertRowIntoTableA]



class InsertRow(object):
    label="Insert Row"
    description="Inserts a row into a table"
    

    def getParameterInfo(self):
        parameters = [
            arcpy.Parameter(name="in_table", displayName="Table", datatype="DETable", parameterType="Required", direction="Input"),
            arcpy.Parameter(name="row", displayName="Row", datatype="GPValueTable", parameterType="Required", direction="Input"),
            arcpy.Parameter(name="out_table", displayName="Edited Table", datatype="DETable", parameterType="Derived", direction="Output"),
            ]
        parameters[1].columns = [
            ["GPString", "Field"],
            ["GPString", "Value"]
            ]
        return parameters
        

    def updateParameters(self, parameters):
        par = {p.name: p for p in parameters}
        
        in_table = str(par["in_table"].value)
        # reset fields if no table is selected
        if in_table == "None":
            par["row"].value = None
            return
        # get fields from the table
        target_fields = [
            f.name
            for f in arcpy.ListFields(in_table)
            if f.type not in ("OID", "GlobalID", "Geometry")
            ]
        # get currently loaded fields
        current_fields = []
        if par["row"].value is not None:
            current_fields = [
                f
                for f, v in par["row"].value
                ]
        # if these don't match, a different table was selected -> change fields
        if current_fields != target_fields:
            par["row"].value = [[f, None] for f in target_fields]


    def execute(self, parameters, messages):
        par = {p.name: p for p in parameters}
        # get fields with user input
        row = [
            [field, value]
            for field, value in par["row"].value
            if value not in ('', None)
            ]
        fields, values = list(zip(*row))
        # insert the new row
        # all values are str, but the InsertCursor should take care of the conversion
        with arcpy.da.InsertCursor(str(par["in_table"].value), fields) as cursor:
            cursor.insertRow(values)
        # set the output parameter
        par["out_table"].value = par["in_table"].value



class InsertRowIntoTableA(object):
    label="Insert Row into TableA"
    description="Inserts a row into TableA"
    

    def getParameterInfo(self):
        parameters = [
            arcpy.Parameter(name="in_table", displayName="TableA", datatype="DETable", parameterType="Required", direction="Input"),
            arcpy.Parameter(name="ID_A", displayName="ID_A", datatype="GPLong", parameterType="Required", direction="Input"),
            arcpy.Parameter(name="TEXT_A", displayName="TEXT_A", datatype="GPString", parameterType="Required", direction="Input"),
            arcpy.Parameter(name="out_table", displayName="Edited TableA", datatype="DETable", parameterType="Derived", direction="Output"),
            ]
        return parameters
        

    def execute(self, parameters, messages):
        par = {p.name: p for p in parameters}
        # get the values
        fields = ["ID_A", "TEXT_A"]
        values = [
            par[f].value
            for f in fields
            ]
        # insert the new row
        with arcpy.da.InsertCursor(str(par["in_table"].value), fields) as cursor:
            cursor.insertRow(values)
        # set the output parameter
        par["out_table"].value = par["in_table"].value

 

JohannesLindner_0-1673948708318.png

 

JohannesLindner_1-1673948730329.png

 

JohannesLindner_2-1673948815911.png

 

 


Have a great day!
Johannes

View solution in original post

2 Replies
DanPatterson
MVP Esteemed Contributor

No.  You would have to create a table, add your stuff and merge.  Python scripting would allow for an InsertCursor to update an existing table


... sort of retired...
0 Kudos
JohannesLindner
MVP Frequent Contributor

As Dan said, there's no out of the box tool. If you need that functionality in Model Builder, you have to create that tool yourself.

Below are two quick examples. You can save that script as a Python toolbox (.pyt), load that into ArcGIS Pro, and then drag the tools in to your model.

# -*- coding: cp1252 -*-

import arcpy


class Toolbox(object):
    def __init__(self):
        self.label = "Utility"
        self.alias = "utility"
        self.tools = [InsertRow, InsertRowIntoTableA]



class InsertRow(object):
    label="Insert Row"
    description="Inserts a row into a table"
    

    def getParameterInfo(self):
        parameters = [
            arcpy.Parameter(name="in_table", displayName="Table", datatype="DETable", parameterType="Required", direction="Input"),
            arcpy.Parameter(name="row", displayName="Row", datatype="GPValueTable", parameterType="Required", direction="Input"),
            arcpy.Parameter(name="out_table", displayName="Edited Table", datatype="DETable", parameterType="Derived", direction="Output"),
            ]
        parameters[1].columns = [
            ["GPString", "Field"],
            ["GPString", "Value"]
            ]
        return parameters
        

    def updateParameters(self, parameters):
        par = {p.name: p for p in parameters}
        
        in_table = str(par["in_table"].value)
        # reset fields if no table is selected
        if in_table == "None":
            par["row"].value = None
            return
        # get fields from the table
        target_fields = [
            f.name
            for f in arcpy.ListFields(in_table)
            if f.type not in ("OID", "GlobalID", "Geometry")
            ]
        # get currently loaded fields
        current_fields = []
        if par["row"].value is not None:
            current_fields = [
                f
                for f, v in par["row"].value
                ]
        # if these don't match, a different table was selected -> change fields
        if current_fields != target_fields:
            par["row"].value = [[f, None] for f in target_fields]


    def execute(self, parameters, messages):
        par = {p.name: p for p in parameters}
        # get fields with user input
        row = [
            [field, value]
            for field, value in par["row"].value
            if value not in ('', None)
            ]
        fields, values = list(zip(*row))
        # insert the new row
        # all values are str, but the InsertCursor should take care of the conversion
        with arcpy.da.InsertCursor(str(par["in_table"].value), fields) as cursor:
            cursor.insertRow(values)
        # set the output parameter
        par["out_table"].value = par["in_table"].value



class InsertRowIntoTableA(object):
    label="Insert Row into TableA"
    description="Inserts a row into TableA"
    

    def getParameterInfo(self):
        parameters = [
            arcpy.Parameter(name="in_table", displayName="TableA", datatype="DETable", parameterType="Required", direction="Input"),
            arcpy.Parameter(name="ID_A", displayName="ID_A", datatype="GPLong", parameterType="Required", direction="Input"),
            arcpy.Parameter(name="TEXT_A", displayName="TEXT_A", datatype="GPString", parameterType="Required", direction="Input"),
            arcpy.Parameter(name="out_table", displayName="Edited TableA", datatype="DETable", parameterType="Derived", direction="Output"),
            ]
        return parameters
        

    def execute(self, parameters, messages):
        par = {p.name: p for p in parameters}
        # get the values
        fields = ["ID_A", "TEXT_A"]
        values = [
            par[f].value
            for f in fields
            ]
        # insert the new row
        with arcpy.da.InsertCursor(str(par["in_table"].value), fields) as cursor:
            cursor.insertRow(values)
        # set the output parameter
        par["out_table"].value = par["in_table"].value

 

JohannesLindner_0-1673948708318.png

 

JohannesLindner_1-1673948730329.png

 

JohannesLindner_2-1673948815911.png

 

 


Have a great day!
Johannes