Select to view content in your preferred language

Insert one (1) row into multiple empty table templates

570
8
Jump to solution
a week ago
SeanLukacs
Occasional Contributor

Hello!  I am still learning the basics. 

I have a several tables in a .gdb that I have assigned as a variable: (The reason being I am building a script tool for handling multiple fc and tables to generate a location based report on facilities and infrastructure.  I am creating template tables to then use when I run summary statistics, and I want to account for instances where some layers Objectid count == 0, in that case, a row is not generated, and then it causes issues when appending each layer to the final table even if to just say "0")

This is what I have:

import os
arcpy.env.workspace = r"path.gdb"

listTables = arcpy.ListTables("*qual_text")
print(listTables)
rows = arcpy.InsertCursor(listTables)<-----this is where it errors out "does not exist"

# Create 25 new rows. Set the initial row ID and distance values
for x in range(1):
row = rows.newRow()
row.setValue("FREQUENCY", 0)
row.setValue("COUNT_OBJECTID", 0)
row.setValue("FAC_TYPE", )
rows.insertRow(row)

# Delete cursor and row objects to remove locks on the data
del row
del rows


print("Row Added")

 

I am getting an error about the tables not existing, but they print out and indeed do exist in the path I set.  do I have bad code formatting?

How do I use InsertCursor (or any other method) to insert 1 row with default values for fields (Already exist)?

 

Thanks in advance!

0 Kudos
1 Solution

Accepted Solutions
TonyAlmeida
MVP Regular Contributor

I don't think you can create a cursor on this list. You must create a cursor for each individual table in that list.

 

Try this,

Iterates table by table
Checks row count
Uses arcpy.da.InsertCursor

import arcpy

arcpy.env.workspace = r"path.gdb"
listTables = arcpy.ListTables("*qual_text")

for table_name in listTables:
    # Get the count of rows in the table
    count_int = int(arcpy.management.GetCount(table_name)[0])
    print(f"Table: {table_name} has {count_int} rows.")

    if count_int == 0:
        print("  Count is zero. Adding default row...")
        try:
            fields = ["FREQUENCY", "COUNT_OBJECTID", "FAC_TYPE"]
            with arcpy.da.InsertCursor(table_name, fields) as cursor:
                cursor.insertRow((0, 0, "No Features Present"))
            print("  Success!")
        except Exception as e:
            print(f"  Failed: {e}")
    else:
        print("  Count is not zero. Skipping.")

 

 

View solution in original post

8 Replies
Neal_t_k
Frequent Contributor

Once you have your list of tables, you need to address each table individually, start here:

listTables = arcpy.ListTables("*qual_text")

     for table in listTables:

          rows = arcpy.InsertCursor(table)

listTables = arcpy.ListTables("*qual_text")

     for table in listTables:

          rows = arcpy.InsertCursor(table)
0 Kudos
DanPatterson
MVP Esteemed Contributor

Code formatting ... the Community Version - Esri Community

to make it easier to read and refer to line numbers


... sort of retired...
SeanLukacs
Occasional Contributor

Thanks for the that

0 Kudos
TonyAlmeida
MVP Regular Contributor

I don't think you can create a cursor on this list. You must create a cursor for each individual table in that list.

 

Try this,

Iterates table by table
Checks row count
Uses arcpy.da.InsertCursor

import arcpy

arcpy.env.workspace = r"path.gdb"
listTables = arcpy.ListTables("*qual_text")

for table_name in listTables:
    # Get the count of rows in the table
    count_int = int(arcpy.management.GetCount(table_name)[0])
    print(f"Table: {table_name} has {count_int} rows.")

    if count_int == 0:
        print("  Count is zero. Adding default row...")
        try:
            fields = ["FREQUENCY", "COUNT_OBJECTID", "FAC_TYPE"]
            with arcpy.da.InsertCursor(table_name, fields) as cursor:
                cursor.insertRow((0, 0, "No Features Present"))
            print("  Success!")
        except Exception as e:
            print(f"  Failed: {e}")
    else:
        print("  Count is not zero. Skipping.")

 

 

HaydenWelch
MVP Regular Contributor

Here's a version that abuses comprehensions and a for...else block to check for empty tables with a single operation:

from arcpy.da import (
    SearchCursor,
    InsertCursor,
)

from arcpy import ListTables

def is_empty(table: str) -> bool:
    """This is a bit of a weird one that abuses a for ... else block
    to test if an iterator is empty. Since we don't want to waste time 
    counting the whole table, we can hop out early and only check the first
    record.
    
    the `else` block only executes if the break is never hit, an empty table
    will never begin iteration, so that break is never hit and False is returned. 
    If the table isn't empty, the loop immediately breaks and the else is skipped returning True
    
    The reason to do this is to take checking if a table is empty from O(n)
    to O(1) since we only ever need to look at the first record.
    """
    with SearchCursor(table, 'OID@') as cur:
        for _ in cur:
            break
        else:
            return True
        return False

def insert_row(table: str, vals: dict) -> None:
    with InsertCursor(table, list(vals.keys())) as cur:
        cur.insertRow(tuple(vals.values()))

def main():
    row = {"FREQUENCY": 0, "COUNT_OBJECTID": 0, "FAC_TYPE": "No Features Present"}
    tables = [t for t in ListTables("*qual_text") if is_empty(t)]
    updates = {
        insert_row(table, row) for table
        for table in tables
    }
    print(f'updated {updates} with default rows')

if __name__ == '__main__':
    main()

 

SeanLukacs
Occasional Contributor

@HaydenWelch  I am getting a syntax error at line 37 of your cell

 

    for table in tables
    ^
SyntaxError: invalid syntax

. Is that For loop okay where it's at? 

HaydenWelch
MVP Regular Contributor

I typoed on that line lol, there's 2 "for table" tokens. Just delete the one on like 36.

 

I shouldn't try to format python code on my phone...

 

I think it was originally "or table" so you'd get a list of tables updated actually and autocorrect sniped me.

0 Kudos
SeanLukacs
Occasional Contributor

@TonyAlmeida This worked, like of the shelf, thank you!!