Streamlit option menu to get menu items dynamically through database

My first day of using Streamlit, and honestly loving it, so please be easy if I don’t understand some basic, though I have done my homework to search the solution. I am trying to get data dynamically into the streamlit_option_menu and could not find an example any where. I have multiple database tables and one of the table has the list of topic which I want to place as the menu items using streamlit_option_menu.

I know the options_menu accepts list of strings as an input, and I have tried multiple ways pandas dataframe, cursor.fetchall() etc. but somehow it doesn’t work as expected. I have a simple table of sd_id and sd_names, and I want to click on sd_names (in the menu) that can then run set of queries to fetch what I want from the relational database.

Any direction or input is highly appreciated.

NB: I don’t have much to share in terms of sample code but I have got the following data coming from maria_db

db_topic = cursor.fetchall()

df = pd.DataFrame(db_topic, columns=cursor.column_names)

I want to place it in the options menu instead of manully typing like in the example below

with st.sidebar:
   selected = option_menu("Main Menu", ["A","B","---"], 

This one gives me the menu options but also has sd_id in front of it and I cannot select any items in the menu

with st.sidebar:
   selected = option_menu("Main Menu", db_topic, 

Hi Youbaraj, i see you’re trying to pass a DataFrame to the option_menu, but this one i believe it uses a list or dict as an argument.

I think i have the same use case in a section of an app I’m developing, where i dynamically get the results on a selectbox, based on the selection made on another:

with col1:
            year = st.selectbox('Selecciona un año:', ['Todos', '2023', '2022', '2021', '2020', '2019', '2018', '2017', '2016', '2015'], index=0)
            panel_options = (['Caracterización', 'Salud', 'Necesidades Especiales', 'Familia']) #, 'Socioeconómica', 'Contexto familiar y social' 
                            #'Características', 'Indice de Masa Corporal', 'Indice de Vulnerabilidad Multidimensional']
            panel = st.selectbox('Selector de panel', panel_options, index=0)
        with col2:
            if year == 'Todos':
                year = None
                encuesta = None
                año = get_encuestasporaño(year)
                # Crea un espacio reservado para el selectbox de la encuesta
                encuesta_selectbox = st.empty()
                # Solo muestra el selectbox de la encuesta si se ha seleccionado un año
                encuesta = encuesta_selectbox.selectbox('Selecciona una encuesta:', ['Todas de este año'] + año, index=0)
                if encuesta == 'Todas de este año':
                    encuesta = None

I select a year, and based off that year, i search in my database using a db pooling function (basically get_connection with something else). My function to get that data and parse it is:

def get_encuestasporaño(year):
    if year:
        query = "SELECT DISTINCT descripcionencuesta FROM sabanarecortada WHERE fechaencuesta = %s;"
        result = execute_query((query, (year,)))
        query = "SELECT DISTINCT descripcionencuesta FROM sabanarecortada;"
        result = execute_query((query,))
    descriptions = [item[0] for item in result] if result else []
    return descriptions

I hope this can help you. Cheers!

Thanks for the helpful info. For now I used a simple trick to convert the dataFrame into list and bind it to the options menu somewhat like this

indexx = df1.iloc[0,0].tolist()
df_topic = df.iloc[:,1].tolist()

with st.sidebar:
    selected = option_menu("मुख्य सूची", df_topic,default_index=indexx)

and used the content.selected (which I plan to change to .index(selected) in next version to speed up the query) to get the contents on the the variable

df_filtered = df[df["topic"].str.contains(selected)]

I have built what I needed in three days, thanks to this amazing streamlit framework. I will take my app for a version 2 update, and will try to work with the other advance functions.

1 Like