Python code not deleting record from database - python

This is the code I have to delete a record from two tables in my database that share the same ID code and I'm not too sure where I've gone wrong. Anything missing? I've checked this a million times
def deletePhoto(photoID):
"""
Middleware function to delete a photo post
"""
#connect to the database
conn, cursor = getConnectionAndCursor()
#create sql to delete from the ratings table
sql = """
DELETE
FROM ratings
WHERE photoID= %s
"""
#set the parameters
parameters = (photoID)
#execute the sql
cursor.execute(sql, parameters)
#create sql to delete from the photo table
sql = """
DELETE
FROM photo
WHERE photoID = %s
"""
#set the parameters
parameters = (photoID)
#execute the sql
cursor.execute(sql, parameters)
#fetch the data
data = cursor.rowcount
#clean up
conn.commit()
cursor.close()
conn.close()

You might try adding a sleeper after your executes.
It can take some time for the server to process your query.
import time
time.sleep(x)
x in seconds

You need to pass in a sequence for the second argument. Using just parentheses does not create a sequence. To top this off, if photoID then that is a sequence too, one that consists of individual characters.
To create a tuple, you need to use a comma. Parentheses are optional here:
parameters = photoID,
or
parameters = (photoID,)
If you find it easier to avoid mistakes here, you could also make it a list:
parameters = [photoID]
You only have to do this once.
As a side note, you can use the MySQLdb connection object, as well as the cursor, as context managers:
with connection, cursor:
ratings_delete = """
DELETE FROM ratings
WHERE photoID= %s
"""
cursor.execute(ratings_delete, (photoID,))
photo_delete = """
DELETE FROM photo
WHERE photoID = %s
"""
cursor.execute(photo_delete, (photoID,))
The with statement will then take care of closing the cursor and connection for you, and if nothing has gone wrong in the block (no exceptions were raised), will also commit the transaction for you.

Related

How to retrieve an output parameter of a stored procedure?

I'm trying to execute an SQL stored procedure which does some inserts an updates, and I pass a parameter called lcLogSessionId to it. During the execution of the procedure this parameter is set to 1 if there are errors, and remains to 0 if everything worked correctly.
In my python script I need to retrieve that value at the end of the execution of the stored procedure.
This is my code:
stored_proc = "Exec [APP].[dataImport] #lcLogSessionId = %s"%(0)
conn = pyodbc.connect(connection_string, autocommit = True)
cursor = conn.cursor()
cursor.execute(stored_proc)
I've tried to fetch the cursor with row = cursor.fetchone(), but i get an error which says "No results. Previous SQL was not a query".
Is there a way to get the value of lcLogSessionId?
pyodbc does not currently implement the optional .callproc() method, so a workaround is required to retrieve output parameters and return values. For SQL Server that involves an anonymous code block to EXEC the stored procedure and then SELECT the values, e.g.,
sql = """\
DECLARE #out nvarchar(max);
EXEC [dbo].[test_for_pyodbc] #param_in = ?, #param_out = #out OUTPUT;
SELECT #out AS the_output;
"""
params = ("Burma!", )
crsr.execute(sql, params)
rows = crsr.fetchall()
while rows:
print(rows)
if crsr.nextset():
rows = crsr.fetchall()
else:
rows = None
More details at the pyodbc wiki:
https://github.com/mkleehammer/pyodbc/wiki/Calling-Stored-Procedures#output-parameters-and-return-values

Selecting record from mySQL via cursors returns an None object

I am writing a script in python 3.x using mysqlconnector.
What I am trying to achieve right now is to check if there is a record inside my db which may be a duplicate to the one I am analyzing right now.
I came up with such code:
def fill_data(self, db_name, data):
cursor = self.cnx.cursor(buffered=True)
isDuplicate = cursor.execute(("SELECT destination FROM {0} WHERE destination = '{1}';")
.format(db_name, data['destination']))
print(cursor.statement)
self.commit()
print(isDuplicate is None)
Though I still get isDuplicate as None object. I tried to check via cursor.statement what statement is being passed to my db: it turned out that while in script I get None obj while passed in db that query works fine.
I also tried SELECT COUNT(1) FROM db_name which also gave me different results.
I am out of ideas: maybe you guys can help me out?
Update:
The solution that works for me was:
q = ("SELECT * FROM {0} WHERE destination = %s AND countryCode = %s AND prefix = %s")
.format(db_name)
cursor.execute(q, (data['destination'], data['country_code'], data['prefix']))
self.cnx.commit()
isDoubled = cursor.fetchone()
So at the end of the day it was all about fetching data from the cursor :)
Maybe the reason of your issue is the way you use execute() method.
Try to make some changes and see what is printed out:
def fill_data(self, db_name, data):
cursor = self.cnx.cursor(buffered=True)
q = 'SELECT count(*) FROM {} WHERE destination = %s'.format(db_name)
duplicate_count = cursor.execute(q, (data['destination'], )).fetchall()
print(duplicate_count)
Why should I provide query parameters this way? (article is on psql, but the core principles are the same as in mysql)
update
If you are still receiving "NoneType" object has no atribute "fetchall", then the error is probably here:
cursor = self.cnx.cursor(buffered=True)
Looks like you are not creating cursor at all. I can take a look at it if you post some code about cnx creation.

Issue with Python Web-Application

I am creating a web application of trails in MA. I want to be able to click on the name of a trail, and have its information displayed. I have a table called 'hiking' with 10 columns. Right now, when I click on the name of a trail, the only thing that displays on the page is ( ), just two parentheses and nothing else. I'm trying to a follow an example a professor gave me, but it seems I'm doing something wrong, but I can't really figure out what.
Any help would be greatly appreciated!!
def getHikeInfo(name):
# connect to db
conn, cursor = getConnectionAndCursor()
# prepare SQL
sql = """
SELECT *
FROM hiking
WHERE name = %s
"""
# run the SQL
cursor.execute(sql, name)
# fetch the results
data = cursor.fetchall()
# clean up
cursor.close()
conn.close()
return data
################################################################################
if __name__ == "__main__":
form = cgi.FieldStorage()
if "name" in form:
name=form['name'].value
print getHikeInfo(name)
From what I understand, you need to put your name query parameter into a tuple:
cursor.execute(sql, (name, ))
And, if you only need a single row from the database, use fetchone():
data = cursor.fetchone()

Why can't I compare these form variables using python in my mysql query?

I am trying to check for a string that is being passed from a form in an html page. So the form picks up the user name and then checks the database if it already has been made. If it hasn't, it goes ahead and creates it. My errors are in the part of the logic that looks up that user name.
Note, I have commented out some areas where various errors have popped up:
import mysql.connector
import web
from mysql.connector import Error
import cgi, cgitb
cgitb.enable()
conn = mysql.connector.connect(host='localhost', database='database', user='root', password='root')
cursor = conn.cursor()
form = cgi.FieldStorage()
username = form.getvalue('username')
password = form.getvalue('password')
# check_existence = """
# SELECT username FROM members WHERE username = '%s'
# """
check_existence = """
SELECT username FROM members WHERE username = %s
"""
# cursor.execute(check_existence, username)
# "Wrong number of arguments during string formatting")
cursor.execute(check_existence, (username))
# ^pushes down to con.commit
# cursor.execute(check_existence, (username,))
# ^wrpmg number of arguments during string formatting
# with comma, the error is in commit, with comma, its in execute
conn.commit()
matches = cursor.rowcount()
Now the error is pointing to conn.commit. Though this is depending on the syntax, sometimes it points to the line above it.
Error:
=> 203 conn.commit()
<class 'mysql.connector.errors.InternalError'>: Unread result found.
args = (-1, 'Unread result found.', None)
errno = -1
message = ''
msg = 'Unread result found.'
In my limited experience, commit() is only used to save (commit) updates to the database. It looks like you're executing a select query, but doing nothing with the results, and the error is related to that. Try moving the commit to the end, or doing away with it. Try using/doing something with the results stored in the cursor. I believe the latter is the solution.
The .commit method was off to a start but it wasn't the only problem with the code. I had two problems though one of them is not posted in the original post, I will explain both.
A) cursor.rowcount returns -1. Not sure why but it does. My understanding of it was that it will return the number of rows. But you can use cursor.fetchall() instead. This will return matches in an array....but if the array is empty, it'll return an empty array.
So I used this logic:
if not(cursor.fetchall()):
the set/array is empty>> Create user
else:
something was found >>dont create user
B) This was in the rest of my code. I was checking if the connection was connected:
if conn.is_connected():
The problem with doing this is that if you do this after a .execute, it will return false. So I put it higher up in the logic, to check right when it attempts to connect to the database.

Mysqldb Update error with set %s

I have created a database with MySQLdb.
In database I have a table with name student with columns:
id(is int),
id_user(is int),
f_name(is str),
l_name(is str)
I want to update a row.
My code is below:
db=mdb.connect(host="localhost", use_unicode="True", charset="utf8",
user="", passwd="", db="test")
# prepare a cursor object using cursor() method
cursor = db.cursor()
sql="""SELECT id_user FROM student"""
try:
# Execute the SQL command
cursor.execute(sql)
# Commit your changes in the database
db.commit()
except:
# Rollback in case there is any error
db.rollback()
rows = cursor.fetchall()
the=int(7)
se=str('ok')
for row in rows:
r=int(row[0])
if r==the:
sql2 = """UPDATE student
SET f_name=%s
WHERE id_user = %s"""% (se,the)
# Execute the SQL command
cursor.execute(sql2)
# Commit your changes in the database
db.commit()
db.rollback()
# disconnect from server
db.close()
When I run it I take the error there is column with name ok why?
Can anyone help me find what I am doing wrong please?
str doesn't wrap its argument in quotation marks, so your statement is this:
UPDATE student SET f_name=ok WHERE id_user = 7
when it needs to be this:
UPDATE student SET f_name='ok' WHERE id_user = 7
So, either change this line:
SET f_name=%s
to this:
SET f_name='%s'
or else change this line:
se=str('ok')
to this:
se="'" + str('ok') + "'"
Though I recommend reading about SQL injection, which will become a concern as soon as you start using user-supplied data instead of hard-coded values.
You should run the query like this:
sql2 = """UPDATE student
SET f_name = %s
WHERE id_user = %s"""
cursor.execute(sql2, (se, the))
Don't use string interpolation, let the database driver handle passing the parameters for you. Otherwise you have to deal with syntax errors like this, or worse, SQL injection.
More details here.
You should always enclose your data with quotes.
Instead of %s solely use '%s' the only types you dont need it are numeric ones, but even there i would enclose %d with '%d' cos it is more save.
And you should use at least db.escape_string(your_data) before inserting or updating same values into your database.
Or have a look at the pdo-using style of mysqldb:
http://mysql-python.sourceforge.net/MySQLdb.html#some-examples
c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
WHERE price < %s""", (max_price,))

Categories

Resources