I'm trying to connect a MySQL database with python GUI. But this part of code returns a empty set. I'm not sure what's wrong with my code because there are no error codes... Please help!
def ButtonPressed (self):
print("Finding Parts!")
self.ProdNum = self.aVar.get()
print("Entry text was:", self.ProdNum)
self.db = mysql.connector.connect (user='ezhu', password='<password>', host='127.0.0.1', database='centricsit_prices')
self.query = ("SELECT sd, sy, price FROM css_hp WHERE prod_num = '%s'")
self.cursor = self.db.cursor()
self.cursor.execute (self.query, (self.ProdNum))
self.results = self.cursor.fetchall()
print (self.results)
self.cursor.close()
You are missing the comma:
self.cursor.execute (self.query, (self.ProdNum, ))
HERE^
It is quite important since the query parameters are expected to be passed as an iterable. Comma would make it a tuple. Without a comma, you are passing query parameters as a string, which is also an iterable, hence your query is parameterized with a first character of self.ProdNum, hence nothing matched by the select query.
Related
I have gone through:
Error "Previous SQL was not a query" in Python?
MSSQL2008 - Pyodbc - Previous SQL was not a query
How to check if a result set is empty?
However none of them have resolved the issue.
The snippet from my db.py file is as follows:
result = cursor.execute(self.sql,self.params)
if result is None:
self.data = []
else:
self.data = [dict(zip([key[0] for key in cursor.description], row)) for row in result.fetchall()]
cnxn.close()
return self.data
This works for every SQL and stored procedure I have thrown at it except for this one
seq = request.form['seq']
s = 'EXEC sp_add ?, ?'
p = (udf.get_username(), int(seq))
l = Conn.testing(db="testingDatabase",sql=s,params=p)
I get the error:
Previous SQL was not a query
The SQL:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE sp_add
#user nvarchar(50),
#seq int
AS
BEGIN
SET NOCOUNT ON;
insert into tblName (userCol,seqCol) VALUES (#user,#seq)
END
GO
The stored procedure runs and the row gets inserted but the error shows up.
What I did instead was:
result = cursor.execute(self.sql,self.params)
cnxn.close()
return str(result)
This returns:
EXEC sp_add ?, ?
Why does it return that? Why does it return the statement I just passed to it?
In my SP, if I tag on a SELECT statement then the issue goes away.
Any suggestions other than the hack just mentioned?
According to the Python Database API PEP 249 specification, the return value of cursor.execute is not defined. So DB-APIs like pyodbc do not need to define consistent return value.
However, specifically for pyodbc, cursor.execute() returns a <pyodbc.Cursor> object which maintains the description attribute if object contains a value but will be None if an action command:
result = cursor.execute(self.sql, self.params)
if result.descripton is None:
self.data = []
else:
self.data = [
dict(zip([key[0] for key in cursor.description], row))
for row in
result.fetchall()
]
cnxn.close()
return self.data # METHODS INSIDE CLASSES DO NOT REQUIRE RETURN
Consider even a ternary operator:
result = cursor.execute(self.sql, self.params)
self.data = (
[
dict(zip([key[0] for key in result.description], row))
for row in result.fetchall()
]
if result.descripton is not None
else []
)
cnxn.close()
return self.data
I think I have the right idea to do this function but I'm not sure why I get
this error when I test it. Can anyone please help me fix this?
cur.execute(q)
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The
current statement uses 1, and there are 0 supplied.
Current Attempt
def find_dept_courses(db, dept):
'''Return the courses from the given department. Use the "LIKE"
clause in your SQL query for the course name.'''
return run_query(db, '''SELECT DISTINCT Course FROM Courses WHERE
Course LIKE (? + 'dept%')''')
Desired output
find_dept_courses('exams.db', 'BIO')
# [('BIOA01H3F',), ('BIOA11H3F',), ('BIOB10H3F',), ('BIOB33H3F',),
# ('BIOB34H3F',), ('BIOB50H3F',), ('BIOC12H3F',), ('BIOC15H3F',),
# ('BIOC19H3F',), ('BIOC32H3F',), ('BIOC37H3F',), ('BIOC50H3F',),
# ('BIOC58H3F',), ('BIOC59H3F',), ('BIOC61H3F',), ('BIOC63H3F',),
# ('BIOD21H3F',), ('BIOD22H3F',), ('BIOD23H3F',), ('BIOD26H3F',),
# ('BIOD33H3F',), ('BIOD48H3F',), ('BIOD65H3F',)]
query function:
def run_query(db, q, args=None):
"""(str, str, tuple) -> list of tuple
Return the results of running query q with arguments args on
database db."""
conn = sqlite3.connect(db)
cur = conn.cursor()
# execute the query with the given args passed
# if args is None, we have only a query
if args is None:
cur.execute(q)
else:
cur.execute(q, args)
results = cur.fetchall()
cur.close()
conn.close()
return results
While using .execute you need to pass the argument as a list or tuple, here is the sample
# This is the qmark style:
cur.execute("insert into people values (?, ?)", (who, age))
Currently, you are using a placeholder but do not pass any parameters. Secondly, you are concatenating placeholder ? with a data value in LIKE expression.
Simply separate query statement and data value and leave ? by itself:
def find_dept_courses(db, dept):
sql = '''SELECT DISTINCT Course FROM Courses WHERE Course LIKE ?'''
return run_query(db, sql, args=(dept+'%',))
Remove the ? and resolve your sql syntax so dept is treated as a variable e.g. sql should evaluate to
SELECT DISTINCT Course FROM Courses WHERE
Course LIKE 'mydept%'
Note you may be susceptible to sql injection with this method and dept is from user input
I am getting the error:
builtins.NameError: name 'sqlite3' is not defined
on the line
conn = sqlite3.connect(db)
Can anyone please help me fix this?
def run_query(db, q, args=None):
"""(str, str, tuple) -> list of tuple
Return the results of running query q with arguments args on
database db."""
conn = sqlite3.connect(db)
cur = conn.cursor()
# execute the query with the given args passed
# if args is None, we have only a query
if args is None:
cur.execute(q)
else:
cur.execute(q, args)
results = cur.fetchall()
cur.close()
conn.close()
return results
def get_course_instructors(db, course):
'''Return the Course number, sections and instructors for the given course
number.'''
return (run_query(db, '''SELECT CourseNumber, sections, instructors WHERE
course = ?''', (course)))
import sqlite3 # make sure you have this
def get_course_instructors(db, course):
'''Return the Course number, sections and instructors for the given course
number.'''
Get course code, sections and instructors from Courses table, assuming your variable names are "CourseNumber, sections, instructors" in the Courses table.
return run_query(db, '''SELECT Course, Section, Name FROM Courses WHERE course = ?''', (course,))
Make sure you have a comma after (course) in the return statement.
A test case would look like this.
get_course_instructors('exams.db', 'AFSA01H3F')
[('AFSA01H3F', 'LEC01', 'S. Rockel')]
I had a question pertaining to mysql as being used in Python. Basically I have a dropdown menu on a webpage using flask, that provides the parameters to change the mysql queries. Here is a code snippet of my problem.
select = request.form.get('option')
select_2 = request.form.get('option_2')
conn = mysql.connect()
cursor = conn.cursor()
query = "SELECT * FROM tbl_user WHERE %s = %s;"
cursor.execute(query, (select, select_2))
data = cursor.fetchall()
This returns no data from the query because there are single qoutes around the first variable, i.e.
Select * from tbl_user where 'user_name' = 'Adam'
versus
Select * from tbl_user where user_name = 'Adam'.
Could someone explain how to remove these single qoutes around the columns for me? When I hard code the columns I want to use, it gives me back my desired data but when I try to do it this way, it merely returns []. Any help is appreciated.
I have a working solution dealing with pymysql, which is to rewrite the escape method in class 'pymysql.connections.Connection', which obviously adds "'" arround your string. maybe you can try in a similar way, check this:
from pymysql.connections import Connection, converters
class MyConnect(Connection):
def escape(self, obj, mapping=None):
"""Escape whatever value you pass to it.
Non-standard, for internal use; do not use this in your applications.
"""
if isinstance(obj, str):
return self.escape_string(obj) # by default, it is :return "'" + self.escape_string(obj) + "'"
if isinstance(obj, (bytes, bytearray)):
ret = self._quote_bytes(obj)
if self._binary_prefix:
ret = "_binary" + ret
return ret
return converters.escape_item(obj, self.charset, mapping=mapping)
config = {'host':'', 'user':'', ...}
conn = MyConnect(**config)
cur = conn.cursor()
I have been using Psycopg2 to read stored procedures from Postgres successfully and getting a nice tuple returned, which has been easy to deal with. For example...
def authenticate(user, password):
conn = psycopg2.connect("dbname=MyDB host=localhost port=5433 user=postgres password=mypwd")
cur = conn.cursor()
retrieved_pwd = None
retrieved_userid = None
retrieved_user = None
retrieved_teamname = None
cur.execute("""
select "email", "password", "userid", "teamname"
from "RegisteredUsers"
where "email" = '%s'
""" % user)
for row in cur:
print row
The row that prints would give me ('user#gmail.com ', '84894531656894hashedpassword5161651165 ', 36, 'test ')
However, when I run the following code to read a row of fixtures with a Stored Procedure, I get (what looks to me like) an unholy mess.
def get_from_sql(userid):
conn = psycopg2.connect("dbname=MyDB host=localhost port=5433 user=postgres password=pwd")
fixture_cursor = conn.cursor()
callproc_params = [userid]
fixture_cursor.execute("select sppresentedfixtures(%s)", callproc_params)
for row in fixture_cursor:
print row
The resulting output:
('(5,"2015-08-28 21:00:00","2015-08-20 08:00:00","2015-08-25 17:00:00","Team ",,"Team ",,"Final ")',)
I have researched the cursor class and cannot understand why it outputs like this for a stored procedure. When executing within Postgres, the output is in a perfect Tuple. Using Psycopg2 adds onto the tuple and I don't understand why?
How do I change this so I get a tidy tuple? What am I not understanding about the request that I am making that gives me this result?
I have tried the callproc function and get an equally unhelpful output. Any thoughts on this would be great.
This is because you're SELECTing the result of the function directly. Your function returns a set of things, and each "thing" happens to be a tuple, so you're getting a list of stringified tuples back. What you want is this:
SELECT * FROM sppresentedfixtures(...)
But this doesn't work, because you'll get the error:
ERROR: a column definition list is required for functions returning "record"
The solution is to return a table instead:
CREATE OR REPLACE FUNCTION sppresentedfixtures(useridentity integer) RETURNS TABLE(
Fixture_No int,
Fixture_Date timestamp,
...
) AS
$BODY$
select
"Fixtures"."Fixture_No",
"Fixtures"."Fixture_Date",
...
from "Fixtures" ...
$BODY$ LANGUAGE sql