commit 1665408e17e6d4c9237743e5716a333305865703 Author: Andrew Date: Fri Nov 25 14:14:21 2022 +0200 First commit diff --git a/BokehChart.html b/BokehChart.html new file mode 100644 index 0000000..9df0820 --- /dev/null +++ b/BokehChart.html @@ -0,0 +1,52 @@ + + + + + Bokeh Plot + + + + +
+ + + + + \ No newline at end of file diff --git a/CreateTestDatabase.sql b/CreateTestDatabase.sql new file mode 100644 index 0000000..ce140ca --- /dev/null +++ b/CreateTestDatabase.sql @@ -0,0 +1,120 @@ +CREATE DATABASE Project; +CREATE TABLE "Customer" ( + "CustomerID" INTEGER NOT NULL, + "Name" TEXT, + "Age" INTEGER, + PRIMARY KEY("CustomerID") +); +CREATE TABLE "Address" ( + "AddressID" INTEGER NOT NULL, + "CustomerID" INTEGER NOT NULL, + "Street" TEXT, + "Number" INTEGER, + "PostalCode" INTEGER, + "Region" TEXT, + "CountryID" INTEGER NOT NULL, + CONSTRAINT FK_CustomerID + FOREIGN KEY("CustomerID") REFERENCES "Customer"("CustomerID") + ON DELETE CASCADE, + CONSTRAINT FK_CountryID + FOREIGN KEY("CountryID") REFERENCES "Country"("CountryID") + ON DELETE CASCADE, + PRIMARY KEY("AddressID") +); +CREATE TABLE "Country" ( + "CountryID" INTEGER NOT NULL, + "Country" TEXT, + PRIMARY KEY("CountryID") +); +CREATE TABLE "Contact" ( + "ContactID" INTEGER NOT NULL, + "CustomerID" INTEGER NOT NULL, + "Phone" TEXT, + "Mail" TEXT, + PRIMARY KEY("ContactID"), + CONSTRAINT FK_CustomerID + FOREIGN KEY("CustomerID") REFERENCES "Customer"("CustomerID") + ON DELETE CASCADE +); +CREATE TABLE "Shipment" ( + "CustomerID" INTEGER NOT NULL, + "ItemID" INTEGER NOT NULL, + "Date" TEXT, + CONSTRAINT FK_ItemID + FOREIGN KEY("ItemID") REFERENCES "Item"("ItemID") + ON DELETE CASCADE, + CONSTRAINT FK_CustomerID + FOREIGN KEY("CustomerID") REFERENCES "Customer"("CustomerID") + ON DELETE CASCADE +); +CREATE TABLE "Item" ( + "ItemID" INTEGER NOT NULL, + "Name" TEXT, + PRIMARY KEY("ItemID") +); +INSERT INTO Customer VALUES + (10001,"Tomasz Gorczyca",23), + (10002,"Leon Kulikowski",36), + (10003,"Artur Nowak",32), + (10004,"Iwa Cegielska",28), + (10005,"Adriana Polkowska",31), + (10006,"Patrycja Ptaszynska",29); +INSERT INTO Country VALUES + (1,"Czechia"), + (2,"Slovakia"); +INSERT INTO Address VALUES + (100,10003,"Bílokostelecká",77,46331,"Liberec",1), + (102,10005,"Kyselská",167,41801,"Teplice",1), + (103,10001,"Strmá",184,33701,"Rokycany",1), + (104,10004,"Mjr. Archipova",1,26012,"Dolný Kubín",2), + (105,10002,"Rybka",84,34092,"Ružomberok",2), + (106,10006,"Kurtaserskou",136,93201," Veľký Meder",2); +INSERT INTO Contact VALUES + (1, 10001, "+420778756417","sveta4521@badutstore.com"), + (2, 10002, "+421903443108","kimkjersteen@texasaol.com"), + (3, 10003, "+420776121001","shiknikolai@eloltsf.com"), + (4, 10004, "+421066229393","pebkac59@supermantutivie.com"), + (5, 10005, "+420771019248","thodoan@lohpcn.com"), + (6, 10006, "+421907353718","kotimur@playfuny.com"); +INSERT INTO Item VALUES + (1000001,"Liquorice"), + (1000002,"Surströmming"), + (1000003,"Durian"), + (1000004,"Frog"), + (1000005,"Maggot Cheese"), + (1000006,"Balut"), + (1000007,"Blood sausage"), + (1000008,"Vodka"), + (1000009,"Coconut"), + (1000010,"Escargots snail"), + (1000011,"Tarantula"), + (1000012,"Brain curry"), + (1000013,"Chicken feet"), + (1000014,"Hakarl"), + (1000015,"Basashi"), + (1000016,"Molokhia"), + (1000017,"Civet coffee"), + (1000018,"Stinky tofu"); +INSERT INTO Shipment VALUES + (10001,1000001,"15/12/2021"), + (10001,1000005,"11/12/2021"), + (10002,1000008,"01/01/2022"), + (10002,1000007,"11/01/2021"), + (10002,1000010,"11/12/2021"), + (10002,1000006,"02/01/2022"), + (10003,1000011,"05/02/2022"), + (10003,1000004,"07/08/2021"), + (10003,1000017,"04/11/2021"), + (10004,1000006,"12/01/2022"), + (10004,1000003,"17/01/2022"), + (10005,1000003,"25/12/2021"), + (10006,1000002,"09/02/2022"), + (10006,1000001,"11/08/2021"), + (10007,1000003,"15/11/2021"), + (10007,1000002,"18/01/2022"), + (10007,1000008,"19/01/2022"), + (10008,1000017,"21/12/2021"), + (10004,1000013,"10/01/2022"), + (10008,1000002,"25/12/2021"); + + \ No newline at end of file diff --git a/Project.db b/Project.db new file mode 100644 index 0000000..12f57a4 Binary files /dev/null and b/Project.db differ diff --git a/Python Script.py b/Python Script.py new file mode 100644 index 0000000..9322d7f --- /dev/null +++ b/Python Script.py @@ -0,0 +1,263 @@ +try: + from prettytable import PrettyTable +except ImportError: + auth = input( + 'This Python script requires PrettyTable library. Please press ENTER.') + import os + os.system('pip install prettytable') + from prettytable import PrettyTable +try: + from bokeh.io import output_file, show + from bokeh.plotting import figure + from bokeh.models import ColumnDataSource +except ImportError: + import os + os.system('pip install bokeh') + from bokeh.io import output_file, show + from bokeh.plotting import figure + from bokeh.models import ColumnDataSource +import sys +import sqlite3 +try: + sql = sqlite3.connect( + r"Project.db") +except: + print("\nDatabase not found!") +cursor = sql.cursor() + + +def back(): + input('\nPress ENTER to return to main menu...') + main() + + +def header(): + num_fields = len(cursor.description) + field_names = [i[0] for i in cursor.description] + return field_names + + +def showTables(): + tablelist = [] + cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") + maintable = PrettyTable(["Option", "Number"]) + tablenames = cursor.fetchall() + for i in range(len(tablenames)): + a = [x.replace('(', "").replace(')', "").replace("'", "") + for x in tablenames[i]] + tablelist.append(str(a[0])) + maintable.add_row([a[0], i+1]) + print(maintable) + return tablelist + + +# First query - View table + + +def viewTable(): + try: + tablelist = showTables() + choiceTable = int(input("Select table to view: ")) + cursor.execute("SELECT * FROM %s" % (tablelist[choiceTable-1])) + table = PrettyTable(header()) + values = cursor.fetchall() + for i in values: + a = [x.replace('(', "").replace(')', "").replace("'", "") + for x in str(i).split(',')] + table.add_row(a) + print(table) + except Exception as e: + print('\n'+str(e).capitalize()) + back() + + +# Second query - Insert row + + +def insertRow(): + try: + insert = [] + tablelist = showTables() + choiceTable = int(input("Select table to insert values: ")) + cursor.execute("SELECT * FROM %s" % (tablelist[choiceTable-1])) + scriptmain = "INSERT INTO %s VALUES " % tablelist[choiceTable-1] + multi = len(header())-1 + scriptmain = scriptmain + '('+'%s'+',%s'*multi+')' + for i in header(): + inp = input(i + " = ") + if inp.isnumeric() == True: + inp = int(inp) + else: + inp = "'"+inp+"'" + insert.append(inp) + insert = tuple(insert) + cursor.execute(scriptmain % (insert)) + sql.commit() + except Exception as e: + print('\n'+str(e).capitalize()) + sql.rollback() + back() + + +# Third query - Delete row + + +def deleteRow(): + try: + tablelist = showTables() + choiceTable = int(input("Select table to delete values: ")) + cursor.execute("SELECT * FROM %s" % (tablelist[choiceTable-1])) + scriptmain = "DELETE FROM %s WHERE" % (tablelist[choiceTable-1]) + table = PrettyTable(["Option", "Number"]) + count = 1 + for i in header(): + table.add_row([i, count]) + count += 1 + print(table) + choiceColumn = int(input("Select column to delete values: ")) + column = header()[choiceColumn-1] + choiceField = input(column + " = ") + if choiceField.isnumeric() == True: + choiceField = int(choiceField) + else: + choiceField = "'"+choiceField+"'" + scriptmain = scriptmain + ' %s = %s' + cursor.execute(scriptmain % (column, choiceField)) + sql.commit() + except Exception as e: + print('\n'+str(e).capitalize()) + sql.rollback() + back() + + +# Fourth query - Update row + + +def updateRow(): + try: + tablelist = showTables() + choiceTable = int(input("Select table to update values: ")) + cursor.execute("SELECT * FROM %s" % (tablelist[choiceTable-1])) + scriptmain = "UPDATE " + (tablelist[choiceTable-1]) + " SET %s WHERE " + table = PrettyTable(["Option", "Number"]) + count = 1 + for i in header(): + table.add_row([i, count]) + count += 1 + print(table) + choiceColumn = int(input("Select condition column: ")) + column = header()[choiceColumn-1] + contentColumn = input(column + " = ") + if contentColumn.isnumeric() == True: + column = column + " = " + str(contentColumn) + else: + column = column + " = " + "'"+contentColumn + "'" + scriptmain = scriptmain + column + upd = '' + while True: + choiceField = int(input("Select column to be updated: ")) + field = header()[choiceField-1] + contentField = input(field + " = ") + if contentField.isnumeric() == True: + field = field + " = " + str(contentField) + else: + field = field + " = " + "'"+contentField + "'" + upd = upd+", "+field + con = input( + 'Do you want to add another one to be updated? (y for yes, any other key for no) ') + if con == 'y': + continue + else: + break + upd = upd[2:] + cursor.execute(scriptmain % upd) + sql.commit() + except Exception as e: + print('\n'+str(e).capitalize()) + sql.rollback() + back() + + +# Fifth query - Bokeh visualization + + +def bokeh(): + try: + lst = [] + cursor.execute( + "SELECT Item.Name as Item from Shipment INNER JOIN Item on Shipment.ItemID=Item.ItemID ") + items = cursor.fetchall() + for i in items: + i = str(i).replace('(', '').replace(')', '').replace( + "'", "").replace(",", "") + lst.append(i) + order = [i for n, i in enumerate(lst) if i not in lst[:n]] + dct = {} + for i in order: + dct[i] = lst.count(i) + x = list(dct.keys()) + y = list(dct.values()) + sorted_x = sorted(x, key=lambda a: y[x.index(a)], reverse=True) + source = ColumnDataSource(data=dict(x=x, y=y)) + p = figure(x_range=sorted_x, y_range=(0, 9), title="Counts", + toolbar_location=None, tools="", width=700, height=300, sizing_mode='scale_width') + p.vbar(x='x', top='y', width=0.9, legend_field='x', source=source) + p.xgrid.grid_line_color = None + p.legend.visible = False + output_file('BokehChart.html') + show(p) + back() + except Exception as e: + print('\n'+str(e).capitalize()) + back() + +# Sixth query - Many-to-many relation: 2 JOIN clauses + + +def itemCustomer(): + try: + cursor.execute('SELECT Customer.Name as Customer, group_concat(Item.Name, ", ") as Item from Shipment INNER JOIN Customer on Shipment.CustomerID=Customer.CustomerID INNER JOIN Item on Item.ItemID=Shipment.ItemID GROUP BY Customer;') + table = PrettyTable(header()) + final = cursor.fetchall() + for i in final: + table.add_row(list(i)) + print(table) + except Exception as e: + print('\n'+str(e).capitalize()) + back() + + +def main(): + table = PrettyTable(["Option", "Number"]) + table.add_row(['View Table', 1]) + table.add_row(['Insert Row', 2]) + table.add_row(['Delete Row', 3]) + table.add_row(['Update Row', 4]) + table.add_row(['Chart: Number of times each item was ordered', 5]) + table.add_row(['List items each customer has ordered', 6]) + table.add_row(['Quit', 7]) + print(table) + option = input("Select option: ") + if option == '1': + viewTable() + elif option == '2': + insertRow() + elif option == '3': + deleteRow() + elif option == '4': + updateRow() + elif option == '5': + bokeh() + elif option == '6': + itemCustomer() + elif option == '7': + sql.close() + print("Thank you for using!") + sys.exit() + else: + print("\nUnknown option.") + back() + + +if __name__ == '__main__': + main()