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?

  • What is the purpose of identity Column in SQL database?
    • The identity column is to sort the users.
  • What is the purpose of a primary key in SQL database?
    • The primary key is used to organize and individualize for each user.
  • What are the Data Types in SQL table?
    • Numeric and string data types (also blob)
  • Imperative Programming - series of functions
  • Object Oriented Programming - class, objects
  • SQL alchemy is an abstraction
    • An abstraction is a different way to represent something
    • EX: Functions, OOP, cursor and connect (though C&C are more raw)
    • SQL - Structure Query Language
import sqlite3

database = 'instance/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?

- Same for cursor object?

  • Look at conn object and cursor object in VSCode debugger. What attributes are in the object?
  • Is "results" an object? How do you know?
    • An object is data and functions
    • Yes, "results" is an object
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()
(1, 'Thomas Edison', 'toby', 'sha256$yMUC8oQ3nVXiDu8S$bb8128356ec34f1efd35a4384a0a4408443ba67042eb3adc52d63cd7076edf86', '1847-02-11')
(2, 'Nikola Tesla', 'niko', 'sha256$H9xlb44bJcfvWEnL$2def67a834c4b5af7efc1b6fb21ee9a004444dec600416e2c0081d331c145be9', '2023-03-16')
(3, 'Alexander Graham Bell', 'lex', 'sha256$dfHljf5imSCFqOuV$9919838e3447a53cf2b1e7da96a287f25eb5c28a3daa8b5974f1f940a6f05dac', '2023-03-16')
(4, 'Eli Whitney', 'whit', 'sha256$3EcVez7zGcYsd4Y5$f34a20774eef0654e3259e4a66483c05c20ea51b01604aeb0094b9cfdc65b043', '2023-03-16')
(5, 'Indiana Jones', 'indi', 'sha256$BnqS9e3CSgT9Czw3$e14b2ee14fa80aa3f7c5a5b9e12fcc657c749d0bbb43b5fccbf96bf87f9fe25c', '1920-10-21')
(6, 'Marion Ravenwood', 'raven', 'sha256$fSsJzHQ9LrVi9yKI$b25a744622910ef9ac474decd559ea652c538f2b6f8e0d4c7312270c4a00d1f9', '1921-10-21')

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?
  • Explain purpose of SQL INSERT. Is this the same as User init?
import sqlite3

def create():
    name = input("Insert name")
    uid = input("insert uid")
    password = input("Insert Password")
    dob = input("Input birthday (YYYY-MM-DD)")
    
    # 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((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()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/Users/lydiacho/vscode/lyds.github.io/_notebooks/2023-03-16-AP-unit2-4b.ipynb Cell 8 in <cell line: 31>()
     <a href='vscode-notebook-cell:/Users/lydiacho/vscode/lyds.github.io/_notebooks/2023-03-16-AP-unit2-4b.ipynb#X10sZmlsZQ%3D%3D?line=27'>28</a>     cursor.close()
     <a href='vscode-notebook-cell:/Users/lydiacho/vscode/lyds.github.io/_notebooks/2023-03-16-AP-unit2-4b.ipynb#X10sZmlsZQ%3D%3D?line=28'>29</a>     conn.close()
---> <a href='vscode-notebook-cell:/Users/lydiacho/vscode/lyds.github.io/_notebooks/2023-03-16-AP-unit2-4b.ipynb#X10sZmlsZQ%3D%3D?line=30'>31</a> create()

/Users/lydiacho/vscode/lyds.github.io/_notebooks/2023-03-16-AP-unit2-4b.ipynb Cell 8 in create()
     <a href='vscode-notebook-cell:/Users/lydiacho/vscode/lyds.github.io/_notebooks/2023-03-16-AP-unit2-4b.ipynb#X10sZmlsZQ%3D%3D?line=12'>13</a> cursor = conn.cursor()
     <a href='vscode-notebook-cell:/Users/lydiacho/vscode/lyds.github.io/_notebooks/2023-03-16-AP-unit2-4b.ipynb#X10sZmlsZQ%3D%3D?line=14'>15</a> try:
     <a href='vscode-notebook-cell:/Users/lydiacho/vscode/lyds.github.io/_notebooks/2023-03-16-AP-unit2-4b.ipynb#X10sZmlsZQ%3D%3D?line=15'>16</a>     # Execute an SQL command to insert data into a table
---> <a href='vscode-notebook-cell:/Users/lydiacho/vscode/lyds.github.io/_notebooks/2023-03-16-AP-unit2-4b.ipynb#X10sZmlsZQ%3D%3D?line=16'>17</a>     cursor.execute((name, uid, password, dob))
     <a href='vscode-notebook-cell:/Users/lydiacho/vscode/lyds.github.io/_notebooks/2023-03-16-AP-unit2-4b.ipynb#X10sZmlsZQ%3D%3D?line=18'>19</a>     # Commit the changes to the database
     <a href='vscode-notebook-cell:/Users/lydiacho/vscode/lyds.github.io/_notebooks/2023-03-16-AP-unit2-4b.ipynb#X10sZmlsZQ%3D%3D?line=19'>20</a>     conn.commit()

TypeError: argument 1 must be str, not tuple

Updating a User in table in Sqlite.db

Uses SQL UPDATE to modify password

  • What does the hacked part do?
  • Explain try/except, when would except occur?
  • What code seems to be repeated in each of these examples to point, why is it repeated?
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?
  • What is the "f" and {uid} do?
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?
  • Could you refactor this menu? Make it work with a List?
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 - CAUSES IT TO KEEP RUNNING
        
try:
    menu() # start menu
except:
    print("Perform Jupyter 'Run All' prior to starting menu")

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?