Update a Deta database with data_editor

Hi,

I am starting to use Deta Database but I think its documentation is very scarce, especially for CRUD, my question is that I want to update a dataframe with data_editor and have its update saved in an existing Deta database, I have trying this:

update.py
def to_update(df):
#“”“Si el elemento se actualiza, devuelve None. De lo contrario, se plantea una excepción.”“”
return db_ainsurance.update(df)

app.py

Dataframe

    st.markdown("<h5 style='text-align: left;'>Datos históricos de los eventos</h5>", unsafe_allow_html=True)
    df_selected_mes = df_selected_mes[['Fecha', 'Nombre Monitorista', 'Bitácora', 'Cliente', 'Motivo de Entrada', 'Marca', 'Modelo', 'Placas', 'Economico', 'Latitud', 'Longitud', 'Estado', 'Municipio', 'Tramo', 'Estatus', 'Observaciones']]
    #st.dataframe(df_selected_mes)

    def callback1(key_name):
        st.session_state[key_name]

    key_name = 'my_df'
    edited_df = st.data_editor(data=df_selected_mes[['Fecha', 'Nombre Monitorista', 'Bitácora', 'Cliente', 'Motivo de Entrada', 'Marca', 'Modelo', 'Placas', 'Economico', 'Latitud', 'Longitud', 'Estado', 'Municipio', 'Tramo', 'Estatus', 'Observaciones']], 
                           num_rows="dynamic",
                           on_change=callback1,
                           args=[key_name],
                           key=key_name)
    col19, col20, col21, col22, col23 = st.columns([1,1,1,1,1])
    with col21:
        if st.button("Actualizar"):
            edited_cells = st.session_state[key_name]
            ainsurance_db.to_update(edited_cells)
            st.success("¡Actualizado!")

TypeError: to_update() missing 1 required positional argument: ‘key_name’

Hi @ElthonD

The error message suggests that the function to_update() is missing an argument. And this custom function that you had created is currently being used as a suffix after ainsurance_db. Instead it may be expected to be used in the format of to_update(edited_cells) instead (without any prefix or statement in front of it).

Hope this helps!

1 Like

Deta’s SDK is neat.

For update, you need to send which item to update as a dict followed by a key where the update has to be cariied out.

I made a sample streamlit app to handle CRUD for Deta db. See also the docstring in update_deta_db().

"""Sample CRUD on Deta db and streamlit data editor.

requirements.txt:
    streamlit
    deta
"""


import streamlit as st
import pandas as pd
from deta import Deta


DF_HEADER = ['username', 'name', 'email', 'key']


# Connect/create to/a deta db.
deta_db_name = 'email_account_db'
deta_key = st.secrets['DETA_KEY']

deta_ref = Deta(deta_key)
db_ref = deta_ref.Base(deta_db_name)


def get_all_entries_from_deta_db():
    response = db_ref.fetch()
    items: list[dict] = response.items
    return items


def delete_all_enries_in_deta_db():
    items: list[dict] = get_all_entries_from_deta_db()
    for d in items:
        db_ref.delete(d['key'])


def update_deta_db(edited_df):
    """Delete all and Add new entries.
    
    This is a suboptimal method, but is simple without too
    much complications.
    
    Complications to handle are:
    * Updates in the data editor
    * Deleted rows
    * Added rows

    Instead of those complications, we just delete the current entries
    in the deta db and add new entries from the edited df.
    """
    if len(edited_df):
        cnt = 0

        # 1. Delete
        delete_all_enries_in_deta_db()

        # 2. Add
        list_of_dict = edited_df.to_dict('records')
        for d in list_of_dict:
            # There should be username, because the deta db needs a key
            # and our key is the username.
            if d['username'] is None:
                continue
            key = d['username']
            d.pop('key')
            db_ref.put(d, key=key)
            cnt += 1

        if cnt:
            st.success('Deta db is updated')


def main():
    items = get_all_entries_from_deta_db()
    if len(items) < 1:
        df = pd.DataFrame(columns=DF_HEADER)
    else:
        df = pd.DataFrame(items)

    # Hide the key in display. In Deta db, the key is the username.
    edited_df = st.data_editor(
        df,
        num_rows="dynamic",
        key='account',
        column_config={"key": None}
    )

    if st.button("Update Deta db"):
        update_deta_db(edited_df)


if __name__ == '__main__':
    main()
2 Likes

Thank you @dataprofessor

Yes, I was certainly missing arguments and I already adjusted it to my methods and with the CRUD method suggested by @ferdy it worked for me.

Thanks again and I love your streamlit video tutorials on Youtube.

Thank you @ferdy

It’s just what I needed. Yes, it is certainly not an optimal method but it is quite functional and even more so for the application I am developing that will not be scalable.

I learned a lot.

Thanks again.

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