Read things out of database WHERE 'id'= - python

I am trying to build an examine (Dutch = overhoor) program in Python. Here's my code:
cursor = cnx.cursor()
willekeurig = random.randint(0,9)
query = ('SELECT FRwoord, NLwoord FROM unite8app1 WHERE "id"=willekeurig')
cursor.execute(query)
for (NLwoord, FRwoord) in cursor:
print("Wat is de vertaling van: " + FRwoord + "?")
vertaling = input()
if vertaling == NLwoord:
print("Well done")
else:
print("Helaas")
for (FRwoord, NLwoord) in cursor:
print(FRwoord,NLwoord)
print(query)
cnx.close
I am trying to get a random question based upon the id of that question in my database. I tried some alternatives like:
WHERE 'id'=1
WHERE 'ID'=1
etc
But it doesn't want to work if I run my program (after pressing enter) it says that NLwoord and FRwoord aren't defined, but when I remove that bit of code it works just fine. (if I have just 1 item in my database)
My question is how to grab a random id from my database? I have included some pictures of the database.
http://updo.nl/file/37e39c15.JPG
http://updo.nl/file/1de64d64.JPG

Right now you are not passing the value of willekeurig, but the text willekeurig. Try these two lines for your query & execute insted:
query = "SELECT FRwoord, NLwoord FROM unite8app1 WHERE id=%s"
cursor.execute(query, (willekeurig,))

Have you tried this without any quotes around id?
You should also be able to use:
SELECT FRwoord, NLwoord FROM unite8app1 ORDER BY RAND() LIMIT 1

Related

Populating a QTableWidget in a PyQt5 GUI with a result returned from a stored procedure in MySQL

I have made a GUI in PyQt5 that allows you to deal with a database. There is an insert button which allows you to insert data into a database and then using a stored procedure whose parameter is a MySQL query in string format, it passes a select query to the stored procedure whose where clause consists of values just entered.
`
def insert(self):
try:
self.table.setRowCount(0)
QEmpID = self.lineEmpID.text() + "%"
QFName = self.lineFName.text() + "%"
QLName = self.lineLName .text() + "%"
QSalary = self.lineSalary.text() + "%"
QTask = self.lineTask.text() + "%"
mydb = mc.connect(host="localhost",username="root",password="",database="Office")
mycursor = mydb.cursor()
selectQuery = "SELECT * From Employee WHERE EmpID like '{}' and FirstName like '{}' and LastName like '{}' and Salary like '{}' and Task like '{}'".format(QEmpID, QFName,QLName,QSalary,QTask)
QEmpID = self.lineEmpID.text()
QFName = self.lineFName.text()
QLName = self.lineLName.text()
QSalary = self.lineSalary.text()
QTask = self.lineTask.text()
insertQuery = "INSERT INTO Employee Values({},'{}','{}',{},'{}')".format(QEmpID,QFName, QLName, QSalary, QTask)
mycursor.execute(insertQuery)
mydb.commit()
insertResult = mycursor.fetchall()
mycursor.callProc('fetchData',[selectQuery])
for result in mycursor.stored_results():
selectResult = result.fetchall()
for row_number,row_data in enumerate(selectResult):
self.table.insertRow(row_number)
for column_number,data in enumerate(row_data):
self.table.setItem(row_number,column_number,QTableWidgetItem(str(data)))
except mc.Error as e:
print(e)
The above is my python code for the insert function which is then connected to the insert button.
`
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `fetchData`(in query1 varchar(1000))
begin
set #q = query1;
PREPARE stmt from #q;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
end$$
DELIMITER ;
The above is my stored procedure which executes a query passed to it in string format.
However, when I type in the record to be inserted into the fields and then press Insert, the following shows up without any tracebacks or error reports in the IDLE Shell:
The thing is, the record does get inserted into the database and I think the issue is with the calling of stored procedure with a select query passed to it and whose result can then be populated into the QTableWidget.
I can't think of anything right now. Help is needed.
Thank you!

sqlite3.OperationalError: incomplete input on my code

Can someone help me understand what's incomplete about my code, no matter what I try I keep getting the sqlite3.OperationalError: incomplete input. My code is
editor = Tk()
editor.title('Edit Record')
editor.geometry('400x400')
#Creating database
conn = sqlite3.connect('Student_info.db')
c = conn.cursor()
record_id = delete_box.get()
#Query the database
c.execute("SELECT * FROM Student_info WHERE oid ="+(record_id))<-----
records = c.fetchall()
The line that sublime is referring to is the one I've drawn an arrow to, if anyone could help that would be great!
Your syntax for execute() is off. You should be using a prepared statement as the first parameter, followed by a tuple of parameters as the second function parameter:
record_id = delete_box.get()
c.execute("SELECT * FROM Student_info WHERE oid = %s", (record_id,))
records = c.fetchall()

Psycopg2 query remove \n from args

Im using python3 and postgres 11.5.
This is the script :
a = cursor.execute("SELECT tablename FROM pg_catalog.pg_tables limit 5")
for table in a:
cursor.execute("SELECT * FROM pg_prewarm(public.%s)", [table[0]])
a query gets some table names , and the loop query should run table name as the %s.
but for some reason i get the arg table[0] with // /n in the query and its messing it up.
if i print a results i get table names as tuple:
[('sa1591354519',), ('sa1591397719',), ('sa1591397719',)]
so [table[0]] is a string.
the error i get:
1574683839 [16177], ERR, execute ({'Error while connecting to PostgreSQL': SyntaxError('syntax error at or near "\'sa1591440919\'"\nLINE 1: SELECT * FROM pg_prewarm(public.\'sa1591440919\')\n ^\n')},)
what can i do ?
The errors don't have anything to do with the newlines you see, which are just an artifact of the error message. If you were to print out the error, would see:
syntax error at or near "'sa1591440919'"
LINE 1: SELECT * FROM pg_prewarm(public.'sa1591440919')
^
In other words, Postgres doesn't like the table name you're passing because it contains quotes. This is happening because you're trying to treat the table names like a normal query parameter, which causes psycopg to quote them...but that's not what you want in this case.
Just replace your use of query templating with normal Python string substitution:
a = cursor.execute("SELECT tablename FROM pg_catalog.pg_tables limit 5")
for table in a:
cursor.execute("SELECT * FROM pg_prewarm(public.%s)" % (table[0]))
But this won't actually work, because cursor.execute doesn't return a value, so a will be None. You would need to do something like:
cursor.execute("SELECT tablename FROM pg_catalog.pg_tables limit 5")
a = cursor.fetchall()
for table in a:
...

Python Sqlite UPDATE multiple values

Is there a way to do these two updates in a single instruction?
cur.execute("UPDATE table_name1 SET email = 'foo#bar.com' WHERE id = 4")
cur.execute("UPDATE table_name1 SET phone = '0400-123-456' WHERE id = 4")
I've tried all sort of variations but can't get it to work.
Edit: I want to pass email, phone and I'd as parameters.
You're solution opens you up to SQL injections. If you read the first section of the documentation, it specifically says not to do it the way you are proposing:
Never do this -- insecure!
symbol = 'RHAT'
c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)
Do this instead
t = ('RHAT',)
c.execute('SELECT * FROM stocks WHERE symbol=?', t)
So you should change your code to something along the following lines:
conn = sqlite3.connect('connex.db')
cur = conn.cursor()
mobileval = '0400-123-456'
emailval = 'foo#bar.com'
constrain = 4
q = "UPDATE licontacts310317 SET (?, ?)
WHERE (?)=(?)"
cur.execute(q, (liemailval, limobileval, id, constrain) )
conn.commit()
conn.close()
I haven't tested it, but hopefully you get the idea =)
The following works: Its just standard SQL at this point.
cur.execute("""UPDATE table_name1
SET email = 'foo#bar.com', phone = '0400-123-456'
WHERE id = 4""")
I was facing a similar issue with my own code and was able to get my code working using the following:
cur.execute("UPDATE licontacts310317 SET liemail=?, limobile=? WHERE id=? ", (liemailval, limobileval, constrain))
Someone else already commented this, but it's better to use the ? placeholder and not the string formatting operations because those leave your db vulnerable to SQL injection attacks (basically, hackers).
OK. I made a solution that works with parameters.
First thanks to David for his original answer. It had a small syntax error (corrected in the comments for that answer) but it was enough to help me work out how to get it working without parametising.
(Note:I think David posted his reply before I edited the question to add the need to working with parameters.)
Then this answer helped me parametise the solution.
Here is my solution to the question. I'm poting it in case someone else has the same problem because I did quite a bit of searching before posting the original question and couldn't find the answer.
conn = sqlite3.connect('connex.db')
cur = conn.cursor()
mobileval = '0400-123-456'
emailval = 'foo#bar.com'
constrain = 4
cur.execute("UPDATE licontacts310317 SET liemail=%s, limobile=%s
WHERE %s=?" % (liemailval, limobileval, id), (constrain,))
conn.commit()
conn.close()
Use Dictionaries!
They seem to work well:
cur.execute(
"""UPDATE table_name1
SET email =:email,
phone =:phone
WHERE id = 4
""",
{"email": "foo#bar.com", "phone": '0400-123-456'}
)
So you can just post a dictionary in like so, provided they contain the keys:
cur.execute(
"""UPDATE table_name1
SET email =:email,
phone =:phone
WHERE id = 4
""",
the_dictionary
)
Where the_dictionary = {"email": "foo#bar.com", "phone": "0400-123-456"}. You can put in as many as you'd like. This seems more readable as well I feel.

How do you read individual values from the same row in a database with sqlite?

I am attempting to read 2 values from the same row in a database but I am only good enough to read the entire line at once. I have added all the code that I think will be relevant:
def find(search, term):
# Helper function for the find function.
with connect("GTINb.db") as db:
cursor = db.cursor()
sql = "select * from GTINb where {} = ?".format(search)
cursor.execute(sql,(term,))
db.commit()
results = cursor.fetchall()
new = str(term)
if results:
results = str(results)
temp = open('temp.txt', 'a')
temp.write(results)
temp.write('\n')
temp.close()
with connect("GTINb.db") as db:
cursor.execute("UPDATE GTINb SET stockcur=stockcur-1 WHERE GTIN8=(?)",(new,))
cur = cursor.execute("SELECT stockcur from GTINb by (?)",(new,))
re = cursor.execute("SELECT restock from GTINb by (?)",(new,))
if cur < re:
cursor.execute("UPDATE GTINb SET stockcur=stockcur+10 WHERE GTIN8=(?)",(new,))
return print('More stock has been ordered in as stocks were low')
else:
return
else:
temp = open('temp.txt', 'a')
temp.write('Product not found')
temp.write('\n')
temp.close()
return
I am currently getting the error sqlite3.OperationalError: near "(": syntax error, and have tried replacing the '(?)' with %s, (%s) and ? with no success, coming up with the following error messages:
sqlite3.OperationalError: near "12345670": syntax error // where 12345670 was the input represented by new
sqlite3.OperationalError: near "(": syntax error
sqlite3.OperationalError: near "?": syntax error
Is there another way of doing this or have I made a simple mistake?
None of the SQL statements you've written are valid SQL. Please consult the SQLite documentation for the valid syntax.
Briefly:
UPDATE GTINb SET stockcur=stockcur-1 WHERE GTIN8=(?)
SELECT stockcur from GTINb by (?)
SELECT restock from GTINb by (?)
should be
UPDATE GTINb SET stockcur=stockcur-1 WHERE GTIN8 = ?
SELECT stockcur FROM GTINb WHERE GTIN8 = ?
SELECT restock FROM GTINb WHERE GTIN8 = ?
although the first one will probably execute with the unneeded parentheses.
Once you have your SQL working you will find that the second two statements can be combined into
SELECT stockcur, restock FROM GTINb WHERE GTIN8 = ?
which I believe is what you were asking about.

Categories