Database Programming is Program with Data

The Tri 2 Final Project is an example of a Program with Data.

Prepare to use SQLite in common Imperative Technique

Schema of Users table in Sqlite.db

Uses PRAGMA statement to read schema.

Describe Schema, here is resource Resource- What is a database schema? A database Schema is a blue print or a plan tha make up a database. It helps make up the data elements and tables without the user.

  • What is the purpose of identity Column in SQL database? The purpose is to provide a identifier to each row of the table
  • What is the purpose of a primary key in SQL database? The primary key makes a column or a certain amount of colums the idenitifies each row
  • What are the Data Types in SQL table? Booleans, integers, strings, OOP
import sqlite3

database = 'files/sqlite.db' # this is location of database

def schema():
    
    # Connect to the database file
    conn = sqlite3.connect(database)

    # Create a cursor object to execute SQL queries
    cursor = conn.cursor()
    
    # Fetch results of Schema
    results = cursor.execute("PRAGMA table_info('users')").fetchall()

    # Print the results
    for row in results:
        print(row)

    # Close the database connection
    conn.close()
    
schema()
(0, 'id', 'INTEGER', 1, None, 1)
(1, '_name', 'VARCHAR(255)', 1, None, 0)
(2, '_uid', 'VARCHAR(255)', 1, None, 0)
(3, '_password', 'VARCHAR(255)', 1, None, 0)
(4, '_dob', 'DATE', 0, None, 0)

Reading Users table in Sqlite.db

Uses SQL SELECT statement to read data

  • What is a connection object? After you google it, what do you think it does? A connection object is an object that represents a connection to the database and is used to allow the programmer to execute commands
  • Same for cursor object? A cursor object allows the programmer to fetch data row by row and perform different operations
  • Look at conn object and cursor object in VSCode debugger. What attributes are in the object? The attributes in the conn object include many different things like varibles, row_factory and total changes
  • Is "results" an object? How do you know? Results is an object and you would know because it is set equal to cursor.execute()
import sqlite3

def read():
    # Connect to the database file
    conn = sqlite3.connect(database)

    # Create a cursor object to execute SQL queries
    cursor = conn.cursor()
    
    # Execute a SELECT statement to retrieve data from a table
    results = cursor.execute('SELECT * FROM users').fetchall()

    # Print the results
    if len(results) == 0:
        print("Table is empty")
    else:
        for row in results:
            print(row)

    # Close the cursor and connection objects
    cursor.close()
    conn.close()
    
read()
(6, 'Caleb', 'CEN', 'password', '2006-04-14')
(7, 'Eli', '9876', 'hello', '2005-03-21')
(8, 'Harley', 'dog', 'dogssss', '2008-05-10')
(9, 'Charlie', 'dog2', 'dogzzzz', '2023-01-14')

Create a new User in table in Sqlite.db

Uses SQL INSERT to add row

  • Compore create() in both SQL lessons. What is better or worse in the two implementations? In the create function it uses the data and takes the user input to create the users. 4.a can be used for simpler things while 4.b is used for more complex things
  • Explain purpose of SQL INSERT. Is this the same as User init? The SQL insert statement is udsed to insert rows and data into the database table
import sqlite3

def create():
    name = input("Enter your name:")
    uid = input("Enter your user id:")
    password = input("Enter your Password")
    dob = input("Enter your date of birth '2006-04-14'")
    
    # Connect to the database file
    conn = sqlite3.connect(database)

    # Create a cursor object to execute SQL commands
    cursor = conn.cursor()

    try:
        # Execute an SQL command to insert data into a table
        cursor.execute("INSERT INTO users (_name, _uid, _password, _dob) VALUES (?, ?, ?, ?)", (name, uid, password, dob))
        
        # Commit the changes to the database
        conn.commit()
        print(f"A new user record {uid} has been created")
                
    except sqlite3.Error as error:
        print("Error while executing the INSERT:", error)


    # Close the cursor and connection objects
    cursor.close()
    conn.close()
    
#create()

Updating a User in table in Sqlite.db

Uses SQL UPDATE to modify password

  • What does the hacked part do? The hacked part checks to make sure the length of the password is atleast 2 charaters long and if it is not 2 charaters the code will assum it was hacked.
  • Explain try/except, when would except occur? try/exept is used for errors that could offur when running the code. Except will occur when there is an error that dosen't pass though the try block of code.
  • What code seems to be repeated in each of these examples to point, why is it repeated? It is repaerted to check if the information properly matches where it supposed to go and make sure it in the right spots.
import sqlite3

def update():
    uid = input("Enter user id to update")
    password = input("Enter updated password")
    if len(password) < 2:
        message = "hacked"
        password = 'gothackednewpassword123'
    else:
        message = "successfully updated"

    # Connect to the database file
    conn = sqlite3.connect(database)

    # Create a cursor object to execute SQL commands
    cursor = conn.cursor()

    try:
        # Execute an SQL command to update data in a table
        cursor.execute("UPDATE users SET _password = ? WHERE _uid = ?", (password, uid))
        if cursor.rowcount == 0:
            # The uid was not found in the table
            print(f"No uid {uid} was not found in the table")
        else:
            print(f"The row with user id {uid} the password has been {message}")
            conn.commit()
    except sqlite3.Error as error:
        print("Error while executing the UPDATE:", error)
        
    
    # Close the cursor and connection objects
    cursor.close()
    conn.close()
    
#update()

Delete a User in table in Sqlite.db

Uses a delete function to remove a user based on a user input of the id.

  • Is DELETE a dangerous operation? Why? It can be dangerous because you could delet all of your data and information and it can not be recovered.
  • What is the "f" and {uid} do? f is used to embed expressions inside of string literals. The uid is used to imput the user id that will be used in code
import sqlite3

def delete():
    uid = input("Enter user id to delete")

    # Connect to the database file
    conn = sqlite3.connect(database)

    # Create a cursor object to execute SQL commands
    cursor = conn.cursor()
    
    try:
        cursor.execute("DELETE FROM users WHERE _uid = ?", (uid,))
        if cursor.rowcount == 0:
            # The uid was not found in the table
            print(f"No uid {uid} was not found in the table")
        else:
            # The uid was found in the table and the row was deleted
            print(f"The row with uid {uid} was successfully deleted")
        conn.commit()
    except sqlite3.Error as error:
        print("Error while executing the DELETE:", error)
        
    # Close the cursor and connection objects
    cursor.close()
    conn.close()
    
#delete()

Menu Interface to CRUD operations

CRUD and Schema interactions from one location by running menu. Observe input at the top of VSCode, observe output underneath code cell.

  • Why does the menu repeat? the menu repreats because it is recursive
  • Could you refactor this menu? Make it work with a List? yes you could refactor the menu and make a list with the values
def menu():
    operation = input("Enter: (C)reate (R)ead (U)pdate or (D)elete or (S)chema")
    if operation.lower() == 'c':
        create()
    elif operation.lower() == 'r':
        read()
    elif operation.lower() == 'u':
        update()
    elif operation.lower() == 'd':
        delete()
    elif operation.lower() == 's':
        schema()
    elif len(operation)==0: # Escape Key
        return
    else:
        print("Please enter c, r, u, or d") 
    menu() # recursion, repeat menu
        
try:
    menu() # start menu
except:
    print("Perform Jupyter 'Run All' prior to starting menu")
import sqlite3
from tabulate import tabulate

# Connect to the SQLite database
conn = sqlite3.connect('files/sqlite.db')
cursor = conn.cursor()

# Select all rows from the user table
cursor.execute("SELECT id, _name, _uid FROM users")
rows = cursor.fetchall()

# Defines rows and headers
table = tabulate(rows, headers=["ID", "Name", "User ID"])

print(table)*
  ID  Name     User ID
----  -------  ---------
   6  Caleb    CEN
   7  Eli      9876
   8  Harley   dog
   9  Charlie  dog2

Hacks

  • Add this Blog to you own Blogging site. In the Blog add notes and observations on each code cell.
  • Create a new Table or do something new, sqlite documentation
  • In implementation in previous bullet, do you see procedural abstraction?