Predictive Hacks

How To Add Filters For Querying Databases In Streamlit

streamlit query database filter

In this tutorial, we will show you how you can use filters for databases in Streamlit. We will use PostgresSQL but you can use the same logic everywhere.

The hypothetical database that we are going to use has a table called movies and we want to filter it based on the genre and the language.

SELECT title FROM movies
where
genre = 'Action'
and
language = 'English'

Let’s build a Streamlit app that will have 2 forms so you can filter the database and return the movie titles.

The first step is to get the values of the filters from the database. In other words the unique genres and languages. In this example, we are opening a connection using psycopg2.

import streamlit as st
import psycopg2 as pg2
conn = pg2.connect("your credentials")

genres = sorted(pd.read_sql(con=conn , sql="select distinct(genre) from movies")['genre'])
languages = sorted(pd.read_sql(con=conn , sql="select distinct(genre) from language")['language'])

Of course, if the lists will never change, you can add the values manually as shown below

genres =['Action', 'Crime', 'Drama', 'Comedy', 'Horror', 'Sci-Fi/Fantasy']
languages=['English','French','Spanish','Italian'] 

Now, let’s create the forms.

import streamlit as st
import psycopg2 as pg2
conn = pg2.connect("your credentials")

genres =['Action', 'Crime', 'Drama', 'Comedy', 'Horror', 'Sci-Fi/Fantasy']
languages=['English','French','Spanish','Italian']


st.title('Movie Filtering')

with st.form(key='my_form'):
    genre=st.multiselect('Select Genre', genres)
    language=st.selectbox('Select Language', languages)
    
    submit_button = st.form_submit_button(label='Submit')

The next step is to run the query and return the results. Here is the tricky part.

if submit_button:
    query=f"""SELECT title FROM movies
                where
                {len(genre)}=0 or genre in ({', '.join(["'"+i+"'" for i in genre+['']])}))
                and
                {len(language)}=0 or language in ({', '.join(["'"+i+"'" for i in language+['']])}))"""
    
    df=pd.read_sql(query,con=conn)
    
    st.write(df)

Let me explain what we are doing there. As you can see we are using Python’s F-String to pass variables in the query.

The multi-select form returns a list with the selected values and if there are no values selected, the multi-select will return an empty list. The question is what we are going to do when there is nothing selected and you want to skip the where statement in the query.

We solved this problem using simple mathematical logic. Let’s breakdown the line for genre.

{len(genre)}=0 or genre in ({', '.join(["'"+i+"'" for i in genre+['']])}))

As an example, let’s say that we have selected Action and Crime. The string will be as follows:

 2=0 or genre in ('Action', 'Crime', '')

This will return the rows that have genre Action or Crime. 2=0 is False everywhere and thats why it will not affect the results.

Now, If we have nothing selected the string will be:

 0=0 or genre in ('')

This will return all rows because 0=0 is True everywhere. As you can see, we added an empty string in genre list because if nothing is selected you will end up with an error in your code as shown below:

#This will return an error  because there is nothing in the list
0=0 or genre in ()

#vs

 0=0 or genre in ('')

Share This Post

Share on facebook
Share on linkedin
Share on twitter
Share on email

Leave a Comment

Subscribe To Our Newsletter

Get updates and learn from the best

More To Explore

Python

Image Captioning with HuggingFace

Image captioning with AI is a fascinating application of artificial intelligence (AI) that involves generating textual descriptions for images automatically.

Python

Intro to Chatbots with HuggingFace

In this tutorial, we will show you how to use the Transformers library from HuggingFace to build chatbot pipelines. Let’s