Endless Loop with DataFrame – DEV Community

Trying gr.DataFrame. Used dataframe.change(). Changed the contents of a cell. Pressed enter and it goes into an endless loop. Terminal shows that is continuing and repetitively talks to the database but the UI never refreshes. UI just hangs. If I restart the application I can see that the change did occurred and the database was updated. But how to stop the endless loop? ….thanks.
`import gradio as gr
import pandas as pd
import sqlite3
import asyncio
DATABASE_NAME = “database/test_database.db”
TABLE_NAME = “test_data”
def setup_database():
“””Sets up a simple SQLite database for testing.”””
conn = sqlite3.connect(DATABASE_NAME)
cursor = conn.cursor()
cursor.execute(f”””
CREATE TABLE IF NOT EXISTS {TABLE_NAME} (
id INTEGER PRIMARY KEY,
name TEXT,
age INTEGER,
city TEXT,
salary REAL
)
“””)
# Insert some initial data
initial_data = [
(“Alice”, 30, “New York”, 60000.0),
(“Bob”, 25, “Los Angeles”, 50000.0),
(“Charlie”, 35, “Chicago”, 70000.0),
(“David”, 28, “Houston”, 55000.0),
]
cursor.executemany(f”INSERT INTO {TABLE_NAME} (name, age, city, salary) VALUES (?, ?, ?, ?)”, initial_data)
conn.commit()
conn.close()
def load_data_from_db():
“””Loads data from the SQLite database into a Pandas DataFrame.”””
conn = sqlite3.connect(DATABASE_NAME)
query = f”SELECT id, name, age, city, salary FROM {TABLE_NAME}”
df = pd.read_sql_query(query, conn)
conn.close()
return df
def delete_row_from_db(row_id):
“””Deletes a row from the database based on its ID.”””
conn = sqlite3.connect(DATABASE_NAME)
cursor = conn.cursor()
try:
cursor.execute(f”DELETE FROM {TABLE_NAME} WHERE id = ?”, (row_id,))
conn.commit()
print(f”Deleted row with id: {row_id}”)
except sqlite3.Error as e:
print(f”Error deleting row: {e}”)
conn.rollback()
finally:
conn.close()
def update_database(data):
“””Updates or inserts data into the SQLite database based on changes in the DataFrame.”””
conn = sqlite3.connect(DATABASE_NAME)
cursor = conn.cursor()
try:
output_text = “”
df = pd.DataFrame(data, columns=[“id”, “name”, “age”, “city”, “salary”])
for index, row in df.iterrows():
row_id = row['id']
name = row['name']
age = row['age']
city = row['city']
salary = row['salary']
if pd.isna(row_id):
# Add new row if ID is NaN (newly added row)
cursor.execute(f"INSERT INTO {TABLE_NAME} (name, age, city, salary) VALUES (?, ?, ?, ?)",
(name, age, city, salary))
print(f"Inserted new row: {name}, {age}, {city}, {salary}")
ouput_text = f"Inserted new row: {name}, {age}, {city}, {salary}"
else:
# Update existing row if ID is present
cursor.execute(f"UPDATE {TABLE_NAME} SET name=?, age=?, city=?, salary=? WHERE id=?",
(name, age, city, salary, int(row_id)))
print(f"Updated row with id {row_id}: {name}, {age}, {city}, {salary}")
ouput_text = f"Updated row with id {row_id}: {name}, {age}, {city}, {salary}"
conn.commit()
updated_df = load_data_from_db() # Reload data to reflect changes
return updated_df
except sqlite3.Error as e:
print(f"Database error: {e}")
output_text = f"Database error: {e}"
conn.rollback()
return load_data_from_db()
finally:
conn.close()
print("Update or inserted connection closed")
def create_gradio_ui():
“””Creates the Gradio interface for testing the DataFrame.”””
setup_database() # Ensure the database is set up
with gr.Blocks() as demo:
dataframe = gr.DataFrame(
value=load_data_from_db(),
headers=["id","name", "age", "city", "salary"], # Add "delete_row" header
interactive=True,
static_columns=[0, 1], # Make only some columns editable
row_count=(3, "dynamic"), # Allow adding rows, with a minimum of 3
col_count=(5, "fixed"),
label="Test DataFrame"
)
output_text = gr.Markdown()
dataframe.change(fn=update_database, inputs=[dataframe], outputs=[dataframe]) # Update on change
return demo
if name == “main“:
demo = create_gradio_ui()
demo.launch()`