Python SQLite3 printing result of two combined tables makes problems - python

I have a problem programming a sqlite3 database in Python.
So I made two lists:
idata=[(0,"Ingredient1"),
(1,"Ingredient2")]
This is the first one that holds "Ingredients" and their ID's.
rdata=[(0,"Recipie1",0,1,1)]
And this is the second one that holds "Recipies" their ID's and and three numbers that indicate the ID of the "Ingredients" to be used in this "Recipie".
Then I created two tables that I filled with the data of these lists:
import sqlite3
conn = sqlite3.connect ("Alchemy_Data_Bank.dat")
c = conn.cursor()
c.execute("""
CREATE TABLE IF NOT EXISTS recipie(id, name, iid_1, iid_2, iid_3);
""")
c.executemany("insert into recipie(id, name, iid_1, iid_2, iid_3) values (?,?,?,?,?)", rdata)
c.execute("""
CREATE TABLE IF NOT EXISTS ingredient(id, name);
""")
c.executemany("insert into ingredient(id, name) values (?,?)", idata)
conn.commit()
And now I want to print out the "Recipies" together with their "Ingredients" combined in a table. So I did this:
for p in c.execute("""SELECT DISTINCT recipie.name,
CASE WHEN recipie.iid_1 = ingredient.id THEN ingredient.name end,
CASE WHEN recipie.iid_2 = ingredient.id THEN ingredient.name end,
CASE WHEN recipie.iid_3 = ingredient.id THEN ingredient.name end
FROM recipie, ingredient;"""):
print(p)
c.close()
conn.close()
What I hoped to get as output is somethin like this:
('Recipie1','Ingredient1', 'Ingredient2', 'Ingredient2')
But it printed this:
('Recipie1', None, None, None)
('Recipie1', None, 'Ingredient2', 'Ingredient2')
('Recipie1', 'Ingedient1', None, None)
I think that my problem lies within the CASE WHEN statments as the programm compares recipie.iid_1, recipie.iid_2 and recipie.iid_3 only with one value for ingredient.id at a time.
So far as I've come the solution must be recursive slection in each CASE WHEN statment but I just can't figure out how to do that.
I hope that someone of you can tell me how to do that!
Thanks in advance!!
Cazo0

Try to rewrite a query. e.g.:
qry1 = """select name,
(select name from ingredient where ingredient.id = recipie.iid_1),
(select name from ingredient where ingredient.id = recipie.iid_2),
(select name from ingredient where ingredient.id = recipie.iid_3)
from recipie;"""
rsl = c.execute(qry1)
for r in rsl:
print (r)
see my gist for the whole code:
https://gist.github.com/mh70cz/5cfa595b455e87d7c08da5315b1abd21

Related

update the last entered value from a selection of values in a database with python , mysql

Okay so i have a table which has student id and the student id is used as identifier to edit the column but what if the same student lends a book twice then all the student value will b edited which i don't want....i want the last entered data of student id to b edited and using a Sl.No is not a solution here because its practically complicated.I am using python connector. Please help :) Thanks in advance
code i use right now :
con = mysql.connect(host='localhost', user='root',
password='monkey123', database='BOOK')
c = con.cursor()
c.execute(
f"UPDATE library set `status`='Returned',`date returned`='{str(cal.selection_get())}' WHERE `STUDENT ID`='{e_sch.get()}';")
c.execute('commit')
con.close()
messagebox.showinfo(
'Success', 'Book has been returned successfully')
If I followed you correctly, you want to update just one record that matches the where condition. For this to be done in a reliable manner, you need a column to define the ordering of the records. It could be a date, an incrementing id, or else. I assume that such column exists in your table and is called ordering_column.
A simple option is to use ORDER BY and LIMIT in the UPDATE statement, like so:
sql = """
UPDATE library
SET status = 'Returned', date returned = %s
WHERE student_id = %s
ORDER BY ordering_column DESC
LIMIT 1
"""
c = con.cursor()
c.execute(sql, (str(cal.selection_get()), e_sch.get(), )
Note that I modified your code so input values are given as parameters rather than concatenated into the query string. This is an important change, that makes your code safer and more efficient.

How to escape a #/# (for example 6/8) in the name of a table from a database

I am currently trying to get a list of values from a table inside an SQL database. The problem is appending the values due to the table's name in which I can't change. The table's name is something like Value123/123.
I tried making a variable with the name like
x = 'Value123/123'
then doing
row.append(x)
but that just prints Value123/123 and not the values from the database
cursor = conn.cursor()
cursor.execute("select Test, Value123/123 from db")
Test = []
Value = []
Compiled_Dict = {}
for row in cursor:
Test.append(row.Test)
Value.append(row.Value123/123)
Compiled_Dict = {'Date&Time': Test}
Compiled_Dict['Value'] = Value
conn.close()
df = pd.DataFrame(Compiled_Dict)
The problem occurs in this line
Value.append(row.Value123/123)
When I run it I get that the database doens't have a table named 'Value123'. Since I think it's trying to divide 123 by 123? Unfortunately the table in the database is named like this and I cannot change it, so how do I pull the values from this table?
Edit:
cursor.execute("select Test, Value123/123 as newValue from db")
I tried this and it worked thanks for the solutions. Suggested by Yu Jiaao

MySQL: Parameterized column names in Python

My issue came when I decided to make a method that could handle a variation of queries, instead of coding 3 methods. I wanted to do so as to recycle code.
I have this table:
(I created it in the purpose of this question. You can do it by:
create table example (id int(1), ex1 varchar(15), ex2 varchar(15), ex3 varchar(15));
insert into example values(1, 'whatever11', 'whatever12', 'whatever13');
insert into example values(2, 'whatever21', 'whatever22', 'whatever23');
insert into example values(3, 'whatever31', 'whatever32', 'whatever33');
SO: I was trying to parameterize column names. I have done it in the whereclause all the time, but as I mention earlier, I thought it would be cleaner and more optimal to do just one method ( select %s from example where id=%s), instead of 3 different: (select ex1 from etc, select ex2 from etc.
So I tried this:
So the normal method is this:
def getex1(id):
myCursor=mydb.cursor()
query='select ex1 from example where id=%s'
myCursor.execute(query, (id,))
result=myCursor.fetchone()[0]
print(result) #prints 'whatever11 if id=1'
When I searched how to do parameterized queries, I saw that to do various parameters, you can just do something like input=(param1, param2, and then execute by (query, input), so I tried to do so but with the column name:
here, info is 'ex1', 'ex2' or 'ex3':
def getAllFromExample(info, id):
myCursor = mydb.cursor()
query= 'select %s from example where id=%s'
input = (info, id)
myCursor.execute(query, input)
result = myCursor.fetchone()[0]
print(result) #in this case, prints the column names 'ex1', 'ex2', not the content
My guess is that you can't just do the param by columns, because you are not assigning a value (like in a whereor in a group by, you have an assignment: whatever=value).
Any insights on this? I did quite the research but did not find anything. here it is mentioned this.
Anything you see wrong with the question, ask me and I'll make it clearer!
You cannot parametrizied the table names, you only can do it with the column values, so you would have to do:
def getAllFromExample(info, DNI):
myCursor = mydb.cursor()
query= 'select '+info+' from example where id=%s'
input = (id,)
myCursor.execute(query, input)
result = myCursor.fetchone()[0]
print(result) #in this case, prints the column name

Update SQLITE DB with multiple python lists

I'm attempting to update my sqlite db with 2 python lists. I have a sqlite db with three fields. Name, number, date. I also have three python lists with similar names. I'm trying to figure out a way to update my sqlite db with data from these 2 lists. I can get the db created, and even get a single column filled, but I cant seem to update it correctly or at all. Is there a way to INSERT both lists at once? Rather than INSERT a single column and then UPDATE the db with the other?
Here is what I have so far:
name_list = []
number_list = []
date = now.date()
strDate = date.strftime("%B %Y")
tableName = strDate
sqlTable = 'CREATE TABLE IF NOT EXISTS ' + tableName + '(name text, number integer, date text)'
c.execute(sqlTable)
conn.commit()
for i in name_list:
c.execute('INSERT INTO January2018(names) VALUES (?)', [i])
conn.commit()
I can't seem to get past this point. I still need to add another list of data (number_list) and attach the date to each row.
Here's what I have on that:
for i in number_list:
c.execute('UPDATE myTable SET number = ? WHERE name', [i])
conn.commit()
Any help would be much appreciated. And if you need more information, please let me know.
You can use executemany with zip:
c.executemany('INSERT INTO January2018 (name, number) VALUES (?, ?)', zip(name_list, number_list))
conn.commit()

How to add multiple Columns into Sqlite3 from a for loop in Python

Admittedly I a still very new to both Python and Sqlite3, and I am attempting to add the contents of two lists into a database so that one list is in the first column and the second list shows up in the second column. To this point, I have been unsuccessful. I am defenitely making a fundamental error, and the error message that I get is this: "sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type."
my code is this:
import sqlite3
names = ['Tom', 'Dick', 'Harry']
ids = ['A452', 'B698', 'Kd9f']
conn = sqlite3.connect('testforinput.db')
c = conn.cursor()
c.execute("CREATE TABLE thetable(name TEXT, id TEXT)")
index = 0
for link in names:
idofperson = ids[index]
c.execute("INSERT INTO thetable(name, id)VALUES(?, ?)", ( [link], idofperson ))
index+=1
conn.commit()
conn.close()
The error occurs because of the for loop specifically the "idofperson" variable
The desired outcome is that I would like to have two columns created in sql one being name and the other being id.
Any help would be greatly appreciated.
I think you just change
index =0
for link in names:
idofperson = ids[index]
c.execute("INSERT INTO thetable(name, id)VALUES(?, ?)", ( [link], idofperson ))
to this (use enumrate and change [list] to list, because you pass a list into a column need TEXT type):
for index, link in enumrable(names):
idofperson = ids[index]
c.execute("INSERT INTO thetable(name, id)VALUES(?, ?)", ( link, idofperson ))
your variable index is not increasing.try using the enumerate on for loop. or just add index += 1 after execute
the error is occurring because of the unsupported data type you are trying to push in, you can't store list as it is, you need to change to another supported data types, i like this solution ....it worked for me https://stackoverflow.com/a/18622264/6180263
for your problem, try this:
import sqlite3
names = ['Tom', 'Dick', 'Harry']
ids = ['A452', 'B698', 'Kd9f']
data = zip(names, ids)
conn = sqlite3.connect('testforinput.db')
c = conn.cursor()
c.execute("CREATE TABLE thetable(name TEXT, id TEXT)")
for d in data:
sql = "INSERT INTO thetable (name, id) VALUES ('%s', '%s'); " % d
c.execute(sql)
conn.commit()
conn.close()
I suggest change data to a list of dict, like this [{'name':'Tom', 'id': 'A452'}, {'name':'dick', 'id':'B698'}..]
and you can generate insert sql by data, this make the insert more flexible.

Categories