Styling in dynamic data editor

Summary

Iโ€™m trying to set up a styling in an interactive data editor, i.e. a data editor that has num_rows='dynamic' set.

The initial DataFrame is coming from a database and the dataframe can be edited and complemented by the user and after finished send back to the database to be inserted.

I also like to check the data for validity in terms of the primary key before sending it back to the database. If any rows violate the primary key check Iโ€™d like to highlight them.

Unfortunately, Iโ€™m not able to come up with a solution that styles the rows in a way that Iโ€™m satisfied with.

Steps to reproduce

Code snippet:

import pandas as pd
import streamlit as st
import sqlalchemy
import urllib.parse

from datetime import datetime


# Initialize connection.
# Uses st.cache_resource to only run once.
#@st.cache_resource
def init_connection():
    params = urllib.parse.quote_plus(     
        "DRIVER={ODBC Driver 17 for SQL Server};SERVER="
        + st.secrets["host"]
        + ";DATABASE="
        + st.secrets["database"]
        + ";UID="
        + st.secrets["username"]
        + ";PWD="
        + st.secrets["password"])
    
    return sqlalchemy.create_engine("mssql+pyodbc:///?odbc_connect=%s" % params)

conn = init_connection()
# Perform query.

def run_query(query):
    df = pd.read_sql(query, conn)
    return df

def df_upsert(data_frame, table_name, engine, schema=None, match_columns=None):

    pass
    ### CODE FOR DB UPSERT
    
def writetodb(df):
    df_upsert(df, "PLUKartenrabatt", conn)

def insertcsv(file):
    print(file)
    if(file):
        df_csv = pd.read_csv((file))
        st.session_state.df = pd.concat([st.session_state.df, df_csv], ignore_index=True)
        editor.update(st.session_state.df)
        st.session_state["file_uploader_key"] += 1
        st.experimental_rerun()

def get_starting_df():
    date_cols = {"GueltigVon": {"format": "%d/%m/%Y"}, 
                 "GueltigBis": {"format": "%d/%m/%Y"}}
    df = pd.read_sql('SELECT * from PLUKartenrabatt;', conn, parse_dates=date_cols)
    return df

starting_df = get_starting_df()

if 'df' not in st.session_state:
    st.session_state.df_color_coding = []
    st.session_state.df = st.dataframe(starting_df.style.highlight_max(axis=0))

if "file_uploader_key" not in st.session_state:
    st.session_state["file_uploader_key"] = 0

if "uploaded_files" not in st.session_state:
    st.session_state["uploaded_files"] = []

editor = st.data_editor(st.session_state.df, key="editor", use_container_width=True, num_rows="dynamic")

csv_file = st.file_uploader("Upload CSV", type=([".csv"]), key=st.session_state["file_uploader_key"])

if csv_file:
    st.session_state["uploaded_files"] = csv_file

if st.button("Begin upload"):
    insertcsv(csv_file)

if st.button("Transfer to Database"):
    writetodb(editor)

You may ignore all the DB Connection code.

Expected behavior:

The styling seems to work but I get the following error:

streamlit.errors.StreamlitAPIException: The data type (DeltaGenerator) or format is not supported by the data editor. Please convert your data into a Pandas Dataframe or another supported data format.

Actual behavior:

See above.

Iโ€™d like it to work without the Error. Is this possible? I see limited support for pandas styling in dynamic data editors when googling for the problem.

If the direct way is not working is there any workaround to make this work? Iโ€™m also open to any other idea that established some kind of visual feedback to the user if thereโ€™s a primary key violation with their input

Debug info

  • Streamlit version: 1.25.0
  • Python version: 3.9.5

Thanks a lot for your help!

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.