# LIKE: flexible searching
Using LIKE instead of WHERE we can perform flexible searching.
For example, we might search for people with a surname like 'Do%', and that would match Dot, Doyle, or Douglas.
The percent symbol, %, means here "any character, any length".
Let's say we have this table, users:
| first_name | surname |
|---|---|
| John | Doyle |
| Bob | Smith |
| Jen | Dot |
| Sam | Douglas |
Here's how to use LIKE:
SELECT * FROM users
WHERE surname LIKE 'Do%';
You would get back:
| first_name | surname |
|---|---|
| John | Doyle |
| Jen | Dot |
| Sam | Douglas |
# Matching single characters
If you wanted to match only against "Dot", you can use the underscore character, _.
By doing this:
SELECT * FROM users
WHERE surname LIKE 'Do_';
Only people with three-letter surnames starting with 'Do' would match:
| first_name | surname |
|---|---|
| Jen | Dot |
# Matching within text
You can use the percent symbol and the underscore anywhere within text, and not only at the end. These are perfectly valid:
%thto match text ending with'th'.Do__sto match text starting with'Do', ending with's', and with two characters in between.Bo%bto match text starting with'Bo', ending with'b',and with any number of characters in between.
# Adding searching to our app
We can add searching for movies to our app!
First of all, we'd write the query in database.py:
SEARCH_MOVIE = """SELECT * FROM movies WHERE title LIKE ?;"""
This query will allow us to pass in any search term, such as "%Mat%", and it will return rows that contain that string in the movie title. For example, The Matrix.
We should create a function that allows us to use that query as well. In it, we'll accept a search term and we'll add the % at the start and the end:
def search_movies(search_term):
with connection:
cursor = connection.cursor()
cursor.execute(SEARCH_MOVIE, (f"%{search_term}%",))
return cursor.fetchall()
Then we can make use of it in app.py!
First, let's modify the user menu:
menu = """Please select one of the following options:
1) Add new movie.
2) View upcoming movies.
3) View all movies
4) Add watched movie
5) View watched movies.
6) Add user to the app.
7) Search for a movie.
8) Exit.
Your selection: """
Then we'll need to modify the main loop. At the moment it looks like this:
while (user_input := input(menu)) != "7":
if user_input == "1":
prompt_add_movie()
elif user_input == "2":
movies = database.get_movies(upcoming=True)
print_movie_list("Upcoming", movies)
elif user_input == "3":
movies = database.get_movies()
print_movie_list("All", movies)
elif user_input == "4":
prompt_watch_movie()
elif user_input == "5":
movies = prompt_get_watched_movies()
if movies:
print_movie_list("Watched", movies)
else:
print("That user has watched no movies yet!")
elif user_input == "6":
prompt_add_user()
else:
print("Invalid input, please try again!")
We can add another branch (make sure to change the exit condition of the loop as well!):
while (user_input := input(menu)) != "8":
if user_input == "1":
prompt_add_movie()
elif user_input == "2":
movies = database.get_movies(upcoming=True)
print_movie_list("Upcoming", movies)
elif user_input == "3":
movies = database.get_movies()
print_movie_list("All", movies)
elif user_input == "4":
prompt_watch_movie()
elif user_input == "5":
movies = prompt_get_watched_movies()
if movies:
print_movie_list("Watched", movies)
else:
print("That user has watched no movies yet!")
elif user_input == "6":
prompt_add_user()
elif user_input == "7":
movies = prompt_search_movies()
if movies:
print_movie_list("Movies found", movies)
else:
print("Found no movies for that search term!")
else:
print("Invalid input, please try again!")
And of course, define the prompt_search_movies() function:
def prompt_search_movies():
search_term = input("Enter partial movie title: ")
return database.search_movies(search_term)
We've got very good use out of our print_movie_list() function! That's a good sign that we've done something right.
Excellent job!