Solved it! Turns out I was caching the wrong thing:
@st.cache(allow_output_mutation=True, hash_funcs={Engine: id})
def get_repository() -> Repository:
return Repository(engine=Engine(...), ...)
By caching the actual database connection and not the wrapper object in my code it works.
When I cache a database connection and query like this (via injected dependencies, so I can use it with a repository wrapper) it breaks down
@st.cache(allow_output_mutation=True)
def get_connection() -> Engine:
return sql.create_engine(...)
@st.cache(allow_output_mutation=True)
def query_something(con: Engine) -> pd.DataFrame:
return pd.read_sql(
sql="""
SELECT
*
FROM
information_schema.tables;
""",
con=con,
).head()
con = get_connection()
query = query_something(con)
it breaks down, and I get streamlit.caching.CacheKeyNotFoundError: Key not found in mem cache
.
But if I instead mix it all together, while still keeping the cache decorators:
@st.cache(allow_output_mutation=True)
def get_connection() -> Engine:
return sql.create_engine(...)
@st.cache(allow_output_mutation=True)
def query_something() -> pd.DataFrame:
con = get_connection() # function gets connection directly
return pd.read_sql(
sql="""
SELECT
*
FROM
information_schema.tables;
""",
con=con,
).head()
query = query_something()
Now it works!.. But I had to directly “hack” the connection into query_something
, so this is not an ideal solution.
Why is the first case not working?