Introduction
In previous tutorial todo app using Python-SQLite3 using SQL-query list of tuples to query read and find task inside database. This time we will level up by using a list of Dictionary.
Below is the script that will be modify for read-task and find_task functions.
# main-read.py
# from connect import db_connection
import sqlite3
# connect to the database and returns a connection object
conn = sqlite3.connect('todo.db')
with conn:
c = conn.cursor()
def create_table():
# initializes the database and creates 'todo' table if it doesn't exist
c.execute("""
CREATE TABLE IF NOT EXISTS todo (
id INTEGER PRIMARY KEY,
task TEXT NOT NULL);
""")
print('Table created!')
def create_task():
new_task = input("What is your new task: ")
c.execute("INSERT INTO todo (task) VALUES\
(?)",(new_task,))
# commit function will enable the change will take place
conn.commit()
def read_task():
c.execute("SELECT * FROM todo")
rows = c.fetchall()
for row in rows:
# print(f"{row[0]}- {row[1]}")
print(f"{row['id']}- {row['task']}")
# conn.close()
print("")
def find_task():
# parameter query `like`
task_input = input("Search by task: ")
task_input = task_input.lower()
# method 1 - completed
# param_q = c.execute("SELECT * FROM todo WHERE task LIKE ?", ('%'+task_input+'%',))
# method 2 - completed
sql_query = "SELECT * FROM todo WHERE task LIKE ?"
param_q = c.execute(sql_query, ('%'+task_input+'%',))
# loop param_q
for row in param_q:
print(f"{row[0]}- {row[1]}")
def main():
# create_table()
# greeting
print("*****Todo app*****")
while True:
print("Please choose one only either: ")
print("(i) Insert task")
print("(r) Read/Preview all task")
print("(s) Search task")
print("(q) Quit from the system")
print("\n")
prompt_user = (input("Choose only one: "))
prompt_user = prompt_user.lower()
if prompt_user.lower() == "q":
print("Exit")
break
elif prompt_user == "i":
create_task()
elif prompt_user == "r":
read_task()
elif prompt_user == "s":
find_task()
else:
print("Eror! Please put valid input. \n")
main()
If you look read_task function we loop rows for row[0] which is for id and row[1] for task.
print(f"{row[0]}- {row[1]}")
while find_task function we loop rows for row[0] which is for id and row[1] for task.
print(f"{row[0]}- {row[1]}")
According to Python official website it says that
By default, sqlite3 represents each row as a tuple. If a tuple does not suit your need, you can use the
sqlite3.Rowclass or a customrow_factory
It is recommended that …
While
row_factoryexists as an attribute both on theCursorand theConnection, and it is recommended to setConnection.row_factory, so all cursors created from the connection will use the same row factory.
Let’s see run Sqlite3 as CLI
$ sqlite3 todo.db
Next, let’s open todo.db. You will be prompt into
SQLite version 3.27.2 2019-02-25 16:06:06
Enter ".help" for usage hints.
Now let see the database connection.
sqlite> .databases
main: /home/ahmad/tutorial/sqlite3-tutorial/todo.db
Preview any table inside todo.db database
sqlite> .tables
todo
Command pragma table_info() for table todo.
sqlite> pragma table_info('todo');
0|id|INTEGER|1||1
1|taks|TEXT|1||0
Let’s explain this:
- First row it starts with
0follows byidthat separated by| - Next or second row start with
1follows bytaskwhile separated also like an above| - Both numbers start for each row is a tuple that were a default value in SQLite
- It’s derived from
selectstatement to query data from tabletodo
How-to-Convert-Tuple-to-Dictionary
If you are new to Sqlite3 and haven’t yet install Sqlite you can read how to install SQLITE3 CLI an acronym for Command-Line Interface. This tutorial will guide you on how to operate basic CRUD operation using SQLITE3 database.
To change for both read_task and find_task functions we can use sqlite.Row class.
# connect to the database and returns a connection object
conn = sqlite3.connect('todo.db')
conn.row_factory = sqlite3.Row
c = conn.cursor()
Next, we can replace from row[0] and row[1] into it’s field name to row['id'] and row['task'] for both functions which is read_task and find_task.
Once done, run it and see whether it’s working.
Here is the final source-code.
# main-read.py
# from connect import db_connection
import sqlite3
# connect to the database and returns a connection object
conn = sqlite3.connect('todo.db')
# with conn:
# c = conn.cursor()
conn.row_factory = sqlite3.Row
c = conn.cursor()
def create_table():
# initializes the database and creates 'todo' table if it doesn't exist
c.execute("""
CREATE TABLE IF NOT EXISTS todo (
id INTEGER PRIMARY KEY,
task TEXT NOT NULL);
""")
print('Table created!')
def create_task():
new_task = input("What is your new task: ")
c.execute("INSERT INTO todo (task) VALUES\
(?)",(new_task,))
# commit function will enable the change will take place
conn.commit()
def read_task():
c.execute("SELECT * FROM todo")
rows = c.fetchall()
for row in rows:
# print(f"{row[0]}- {row[1]}")
print(f"{row['id']}- {row['task']}")
# conn.close()
print("")
def find_task():
# parameter query `like`
task_input = input("Search by task: ")
task_input = task_input.lower()
# method 1 - completed
# param_q = c.execute("SELECT * FROM todo WHERE task LIKE ?", ('%'+task_input+'%',))
# method 2 - completed
sql_query = "SELECT * FROM todo WHERE task LIKE ?"
param_q = c.execute(sql_query, ('%'+task_input+'%',))
# loop param_q
for row in param_q:
# print(f"{row[0]}- {row[1]}")
print(f"{row['id']}- {row['task']}")
def main():
# create_table()
# greeting
print("*****Todo app*****")
while True:
print("Please choose one only either: ")
print("(i) Insert task")
print("(r) Read/Preview all task")
print("(s) Search task")
print("(q) Quit from the system")
print("\n")
prompt_user = (input("Choose only one: "))
prompt_user = prompt_user.lower()
if prompt_user.lower() == "q":
print("Exit")
break
elif prompt_user == "i":
create_task()
elif prompt_user == "r":
read_task()
elif prompt_user == "s":
find_task()
else:
print("Eror! Please put valid input. \n")
main()