Displaying SQLite data in a Tkinter GUI - database

So I have a very simply Tkinter GUI which takes an input parameter and inputs it into a SQLite database. I'm looking to create a secondary GUI which will extract this parameter from the SQLite database and display it on the secondary GUI. Can you please help on how to do this? Preferably I want to display this data from the DB on a text field or something of the like.
from Tkinter import *
from PIL import Image, ImageTk
import sqlite3
root = Tk()
root.wm_attributes('-fullscreen','true')
root.title("My Test GUI")
Fullname=StringVar()
conn = sqlite3.connect('Form.db')
cursor=conn.cursor()
def database():
name1=Fullname.get()
cursor.execute('CREATE TABLE IF NOT EXISTS Student (Fullname TEXT)')
cursor.execute('INSERT INTO Student (FullName) VALUES(?)',(name1,))
conn.commit()
def error():
root1 = Toplevel(root)
root1.geometry("150x90")
root1.title("Warning")
Label(root1, text = "All fields required", fg = "red").pack()
def read_from_db():
cursor.execute('SELECT * FROM Student')
data = cursor.fetchall()
print(data)
label_0 = Label(root, text="My Test GUI",width=20,font=("bold", 20))
label_0.place(x=650,y=53)
label_1 = Label(root, text="Name",width=20,font=("bold", 10))
label_1.place(x=550,y=130)
entry_1 = Entry(root,textvar=Fullname)
entry_1.place(x=700,y=130)
Button(root, text='Submit',width=20,bg='brown',fg='white', command=database).place(x=650,y=380)
root.mainloop()
read_from_db()

Within your read_from_db function, instead of printing the value of data you can make a label out of it:
def read_from_db():
cursor.execute("SELECT *, oid FROM Student")
data = c.fetchall()
showData = ''
for data in Student:
showData += str(data) + "\n"
dataLabel = Label(master, text=showData)
playerLabel.grid(row=0, column=0)
conn.commit()
conn.close()

Related

SQLAlchemy and Snowflake Query ID

It's possible to get the Snowflake Query Id when using the snowflake-connector-python, i.e. the sfqid attribute from the cursor object.
Is it possible to get that attribute when using Snowflake's SQLAlchemy Toolkit? The doc page doesn't mention it - https://docs.snowflake.com/en/user-guide/sqlalchemy.html.
Thanks,
Eric
You can use sqlalchemy's execute method and get a reference to the SnowflakeCursor like this:
import os
from sqlalchemy import create_engine
from dotenv import load_dotenv
load_dotenv()
snowflake_username = os.getenv('SNOWFLAKE_USERNAME')
snowflake_password = os.getenv('SNOWFLAKE_PASSWORD')
snowflake_account = os.getenv('SNOWFLAKE_ACCOUNT')
snowflake_warehouse = os.getenv('SNOWFLAKE_WAREHOUSE')
snowflake_database = 'simon_db'
snowflake_schema = 'public'
if __name__ == '__main__':
engine = create_engine(
'snowflake://{user}:{password}#{account}/{db}/{schema}?warehouse={warehouse}'.format(
user=snowflake_username,
password=snowflake_password,
account=snowflake_account,
db=snowflake_database,
schema=snowflake_schema,
warehouse=snowflake_warehouse,
)
)
connection = engine.connect()
results = connection.execute("SELECT * FROM TEST_TABLE")
queryId = results.cursor.sfqid
print(f"queryId = {queryId}")
print(f"results: {results.fetchone()}")
connection.close()
engine.dispose()
This prints out:
queryId = 019edbef-0000-114f-0000-0f9500612j23
results: ('n/a', '2021-01-01')
One way I found was using the function LAST_QUERY_ID, something like this:
results = connection.execute("SELECT * FROM CITIBIKE_TRIPS LIMIT 1").fetchone()
query_id = connection.execute("SELECT LAST_QUERY_ID()").fetchone()
print(query_id)
I get back something like:
$ python test_sqlalchemy.py
('019edb4b-0502-8a31-0000-16490cd95072',)
Might not be the ideal way.

Pandas, how to reset? - Shape of passed values is (1,1), indices imply (3,1)

I'm currently writing some code and am using pandas to export all of the data into csv files. My program runs multiple iterations until it has gone through all of the necessary files. Pandas is re-writing one file each iteration but when it moves onto the next file I need it to reset all of the data (I think).
Structure is roughly:
While loop>a few variables are named>program runs>dataframe=(pandas.DataFrame(averagepercentagelist,index=namelist,columns=header))
This part works with no problem for one file. When moving onto the next file, all of the arrays I use are reset and this I think is why pandas gives the error Shape of passed values is (1,1), indices imply (3,1).
Please let me know if I need to explain it better.
EDIT:
While True:
try:
averagepercentagelist=[]
namelist=[]
columns=[]
for row in database:
averagepercentagelist=["12","23"]
namelist=["Name0","Name1"]
columns=["Average percentage"]
dataframe=(pandas.DataFrame(averagepercentagelist,index=namelist,columns=header))
except Exception as e:
print e
break
SNIPPET:
dataframe= (pandas.DataFrame(averagepercentagelist,index=namelist,columns=header))
currentcalculatedatafrane = 'averages' + currentcalculate
dataframeexportpath = os.path.join(ROOT_PATH,'Averages',currentcalculatedatafrane)
dataframe.to_csv(dataframeexportpath)
FULL PROGRAM SO FAR:
import csv
import os
import re
import pandas
import tkinter as tk
from tkinter import messagebox
from os.path import isfile, join
from os import listdir
import time
ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
indexforcalcu=0
line_count=0
testlist=[]
namelist=[]
header=['Average Percentage']
def clearvariables():
indexforcalcu=0
testlist=[]
def findaverageofstudent(findaveragenumber,numoftests):
total=0
findaveragenumber = findaveragenumber/numoftests
findaveragenumber = round(findaveragenumber, 1)
return findaveragenumber
def removecharacters(nameforfunc):
nameforfunc=str(nameforfunc)
elem=re.sub("[{'}]", "",nameforfunc)
return elem
def getallclasses():
onlyfiles = [f for f in listdir(ROOT_PATH) if isfile(join(ROOT_PATH, f))]
onlyfiles.remove("averagecalculatorv2.py")
return onlyfiles
def findaveragefunc():
indexforcalcu=-1
while True:
try:
totaltests=0
line_count=0
averagepercentagelist=[]
indexforcalcu=indexforcalcu+1
allclasses=getallclasses()
currentcalculate=allclasses[indexforcalcu]
classpath = os.path.join(ROOT_PATH, currentcalculate)
with open(classpath) as csv_file:
classscoredb = csv.reader(csv_file, delimiter=',')
for i, row in enumerate(classscoredb):
if line_count == 0:
while True:
try:
totaltests=totaltests+1
rowreader= {row[totaltests]}
except:
totaltests=totaltests-1
line_count = line_count + 1
break
else:
calculating_column_location=1
total=0
while True:
try:
total = total + int(row[calculating_column_location])
calculating_column_location = calculating_column_location + 1
except:
break
i=str(i)
name=row[0]
cleanname=removecharacters(nameforfunc=name)
namelist.append(cleanname)
findaveragenumbercal=findaverageofstudent(findaveragenumber=total,numoftests=totaltests)
averagepercentagelist.append(findaveragenumbercal)
line_count = line_count + 1
dataframe= (pandas.DataFrame(averagepercentagelist,index=namelist,columns=header))
currentcalculatedatafrane = 'averages' + i + currentcalculate
dataframeexportpath = os.path.join(ROOT_PATH,'Averages',currentcalculatedatafrane)
dataframe.to_csv(dataframeexportpath)
i=int(i)
except Exception as e:
print("ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n",e)
break
def makenewclass():
global newclassname
getclassname=str(newclassname.get())
if getclassname == "":
messagebox.showerror("Error","The class name you have entered is invalid.")
else:
classname = getclassname + ".csv"
with open(classname, mode='w') as employee_file:
classwriter = csv.writer(employee_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
classwriter.writerow(["Name","Test 1"])
root=tk.Tk()
root.title("Test result average finder")
findaveragebutton=tk.Button(root,text="Find Averages",command=findaveragefunc())
findaveragebutton.grid(row=2,column=2,padx=(10, 10),pady=(0,10))
classnamelabel=tk.Label(root, text="Class name:")
classnamelabel.grid(row=1, column=0,padx=(10,0),pady=(10,10))
newclassname = tk.Entry(root)
newclassname.grid(row=1,column=1,padx=(10, 10))
newclassbutton=tk.Button(root,text="Create new class",command=makenewclass)
newclassbutton.grid(row=1,column=2,padx=(0, 10),pady=(10,10))
root.mainloop()
Thanks in advance,
Sean
Use:
import glob, os
import pandas as pd
ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
#extract all csv files to list
files = glob.glob(f'{ROOT_PATH}/*.csv')
print (files)
#create new folder if necessary
new = os.path.join(ROOT_PATH,'Averages')
if not os.path.exists(new):
os.makedirs(new)
#loop each file
for f in files:
#create DataFrame and convert first column to index
df = pd.read_csv(f, index_col=[0])
#count average in each row, rond and create one colum DataFrame
avg = df.mean(axis=1).round(1).to_frame('Average Percentage')
#remove index name if nncessary
avg.index.name = None
print (avg)
#create new path
head, tail = os.path.split(f)
path = os.path.join(head, 'Averages', tail)
print (path)
#write DataFrame to csv
avg.to_csv(path)

Operational error at cursor when creating function in SQLite

I am trying to insert data into my SQLite database, it goes fine until I get the error while creating a function for DB. It sends OperationalError at cursor.
I couldn't find solution for my problem.
Code I'm using:
import sqlite3
from sqlite3 import *
SQL_CREATE_STATEMENT = '''CREATE TABLE password
(id integer PRIMARY KEY NOT NULL,username text, password text, source text)'''
SQL_INSERT_STATEMENT = '''INSERT INTO password (username, password, source)VALUES({},{},{});'''
DATABASE_PATH = 'home/taha/lessons/projects/passStorage/passDB.db'
DATA = dict()
def create_connection(db_file):
try:
conn = sqlite3.connect(db_file)
return conn
except Error as e:
return e
def create_table(connection, sql_commands):
c = connection.cursor()
c.execute(sql_commands)
print('done')
def get_input():
USERNAME = input('username: ')
PASSWORD = input('password: ')
SOURCE = input('source: ')
return USERNAME,PASSWORD,SOURCE
def insert_date(connection, data):
c = connection.cursor()
c.execute(SQL_INSERT_STATEMENT.format(data.values))
def main():
conn = create_connection(DATABASE_PATH)
create_table(conn, SQL_CREATE_STATEMENT)
user_info = get_input()
DATA['username'], DATA['password'], DATA['SOURCE'] = user_info
insert_date(conn, DATA)
if __name__ == '__main__':
main()
I expect no error but it sends this:
c = connection.cursor()
AttributeError: 'OperationalError' object has no attribute 'cursor'
def create_connection(db_file):
try:
conn = sqlite3.connect(db_file)
return conn
except Error as e:
return e # <-- here you return OperationalError instance
AttributeError: 'OperationalError' object has no attribute 'cursor'
Shows that OperationalError has no attribute cursor
Add additional logic that check connection here.
I believe the core of your problem is wrong file path:
DATABASE_PATH = 'home/taha/lessons/projects/passStorage/passDB.db'
But I believe should be
DATABASE_PATH = '/home/taha/lessons/projects/passStorage/passDB.db'

python: range not being executed

App executes but the range doesn't. In my CSV file, it only shows the first entry. I've also come across index out of range errors when scraping other fields. Any help would be appreciated. I'm learning.
import requests
import csv
from bs4 import BeautifulSoup
f = csv.writer(open('salons.csv', 'w'))
f.writerow(['Name'])
pages = []
for i in range(0, 10600):
url = 'http://www.aveda.com/locator/get_the_facts.tmpl?SalonID=' + str(i) +' '
pages.append(url)
for item in pages:
page = requests.get(item)
soup = BeautifulSoup(page.text, 'lxml')
salon_name_list = soup.find(class_='getthefacts__store_meta_info--store_phone')
salon_name_list_items = salon_name_list.find_all('li', class_='phone')
for salon_name in salon_name_list_items:
names = salon_name.contents[0]
f.writerow([names])
The way you tried to find phone numbers is not how you should do. Phone numbers are within a tag under class name phone. Try this instead. It will fetch you the phone numbers you are interested in:
import requests ; import csv
from bs4 import BeautifulSoup
outfile = open('salons.csv','w')
writer = csv.writer(outfile)
writer.writerow(['Name'])
for i in range(0, 10600):
url = 'http://www.aveda.com/locator/get_the_facts.tmpl?SalonID={0}'.format(i)
page = requests.get(url)
soup = BeautifulSoup(page.text, 'lxml')
for salon_name in soup.select('.phone a'):
names = salon_name.text
print(names)
writer.writerow([names])
outfile.close()
Not sure how you have indented your code. Format it properly in the question. And you may not need two for loops.
import requests
import csv
from bs4 import BeautifulSoup
f = csv.writer(open('salons.csv', 'w'))
f.writerow(['Name'])
for i in range(0, 10600):
url = 'http://www.aveda.com/locator/get_the_facts.tmpl?SalonID=' + str(i) +'/'
page = requests.get(url)
soup = BeautifulSoup(page.text, 'lxml')
salon_name_list = soup.find(class_='getthefacts__store_meta_info--store_phone')
salon_name_list_items = salon_name_list.find_all('li', class_='phone')
for salon_name in salon_name_list_items:
names = salon_name.contents[0]
f.writerow([names])

Double Relationship in SQLalchemy

I got following problem in sqlalchemy. I made three different tables in sqlite, the first has no realtion, the second has a relation to the first and the third a relation to the second. So when I want to insert things in the first and the second table everything works fine. When I want to insert datas in the third table I'm getting troubles when I'm going to do it like it's discribed in the tutorial. Here is my code for the three tables:
First table:
# Save_Data_Type.py
from sqlalchemy import ForeignKey
from sqlalchemy import Column, Float, Integer, String
from base import Base
from sqlalchemy.orm import relationship, backref
########################################################################
class Save_Data_Type(Base):
__tablename__ = "save_datas_type"
save_datas_type_id = Column(Integer, primary_key=True)
type_memory = Column(String)
comment = Column(String)
dummy1 = Column(String)
dummy2 = Column(String)
#----------------------------------------------------------------------
def __init__(self, type_memory, comment, dummy1, dummy2):
""""""
self.type_memory = type_memory
self.comment = comment
self.dummy1 = dummy1
self.dummy2 = dummy2
Second Table
# Save_Data.py
from sqlalchemy import ForeignKey
from sqlalchemy import Column, Float, Integer, String
from base import Base
from sqlalchemy.orm import relationship, backref
########################################################################
class Save_Data(Base):
""""""
__tablename__ = "save_datas"
save_datas_id = Column(Integer, primary_key=True)
save_datas_type_id = Column(Integer,ForeignKey("save_datas_type.save_datas_type_id"))
save_datas_type = relationship("Save_Data_Type", backref=backref("save_datas", order_by=save_datas_id))
value = Column(Float)
comment = Column(String)
dummy1 = Column(String)
#----------------------------------------------------------------------
def __init__(self, value, comment, dummy1):
""""""
self.value = value
self.comment = comment
self.dummy1 = dummy1
Third Table
# Station.py
from sqlalchemy import ForeignKey
from sqlalchemy import Column, Integer, Boolean, String
from base import Base
from sqlalchemy.orm import relationship, backref
########################################################################
class Station(Base):
""""""
__tablename__ = "stations"
stations_id = Column(Integer, primary_key=True)
name = Column(String)
password = Column(String)
save_datas_id = Column(Integer,ForeignKey("save_datas.save_datas_id"))
save_datas = relationship("Save_Data", backref=backref("stations", order_by=stations_id))
dummy1 = Column(String)
dummy2 = Column(String)
dummy3 = Column(String)
#----------------------------------------------------------------------
def __init__(self, name, password, dummy1, dummy2, dummy3):
""""""
self.name = name
self.password = password
self.dummy1 = dummy1
self.dummy2 = dummy2
self.dummy3 = dummy3
base.py
# base.py
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
So if I'm going to insert the datas like that:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
import base
from Save_Data_Type import Save_Data_Type
from Save_Data import Save_Data
from Station import Station
engine = create_engine('sqlite:///Database.db', echo=True)
base.Base.metadata.create_all(engine, checkfirst=True)
# create a Session
Session = sessionmaker(bind=engine)
session = Session()
jack = Save_Data_Type("Ring Memory",'In seconds',None,None)
jack.save_datas = [Save_Data(1980,'Sometimes more, sometimes less',None)]
jack.save_datas.stations = [Station('name1','123456',None,None,None)]
session.add(jack)
session.commit()
Nothing is writing in the the third table of the database. How is the usual way to build this relationship?
Thanks in advance,
Johannes
Apart from some typos in the code you posted (see comment from zzzeek), it looks like the problem will be solved by replacing the code:
jack.save_datas.stations = [Station('name1','123456',None,None,None)]
with the one below:
jack.save_datas[0].stations = [Station('name1','123456',None,None,None)]
The reason is the following: in your case you assign/create a stations attribute to a class member. Not only this does not do the right job, it might actualy harm your ORM model.
In the second case you correctly assign the Station instance to the first save_datas.
The more clear code would look like this:
jack = Save_Data_Type("Ring Memory",'In seconds',None,None)
save_data1 = Save_Data(1980,'Sometimes more, sometimes less',None)
jack.save_datas.append(save_data1)
# or: jack.save_datas = [save_data1]
# or (my favourite): save_data1.Save_Data_Type = jack
save_data1.stations = [Station('name1','123456',None,None,None)]
# or... similar to the relationship above

Resources