I want to check if the ID exists already but I get this error:
Not all parameters were used in the SQL statement
Code:
Id = "TEST"
sql = """SELECT * FROM musics WHERE Id = %s"""
dbc.execute(sql, Id)
row = cursor.rowcount
if row == 0:
#NOT EXSIST
The second argument to execute() should be a sequence of values, one for each placeholder token %s in the query.
You did pass a sequence, but not in the way you intended. Strings are sequences, so you actually passed a sequence of four values - T, E, S, T, which is too many values, because the query only has one placeholder token.
Pass the string as a one-element tuple, like so:
args = ("TEST",)
sql = """SELECT * FROM musics WHERE Id = %s"""
dbc.execute(sql, args)
Related
I have this little code
cquery = "SELECT * FROM `workers` WHERE `Username` = (%s)"
cvalue = (usernameR,)
flash(cquery)
flash(cvalue)
x = c1.execute(cquery, cvalue)
flash(x)
usernameR is a string variable I got it's value from a form
x supposed to be the number of rows or some value but it returns none I need it's value for one if.
I tested it with a value that is in the table in one row so thats not the case the the value is not there or something. But if it's not there in that case the x should return 0 or something.
I cant work out what's the problem after several hours.
value of cvalue:
('Csabatron99',)
Edit for solution:
I needed to add the rowcount and fetchall to the code like this:
cquery = "SELECT * FROM `workers` WHERE `Username` = (%s)"
cvalue = (usernameR,)
flash(cquery)
flash(cvalue)
c1.execute(cquery, cvalue)
c1.fetchall()
a = c1.rowcount
cursor.execute() doesn't return anything in the normal case. If you use the multi=True argument, it returns an iterator used to get results from each of the multiple queries.
To get the number of rows returned by the query, use the rowcount attribute.
c1.execute(cquery, cvalue)
flash(c1.rowcount)
I am trying to create a program where a user can enter an operator i.e. <> or = and then a number for a database in pymysql. I have tried a number of different ways of doing this but unfortunately unsuccessful. I have two documents with display being one and importing display into the other document.
Docuemnt 1
def get_pop(op, pop):
if (not conn):
connect();
query = "SELECT * FROM city WHERE Population %s %s"
with conn:
cursor = conn.cursor()
cursor.execute(query, (op, pop))
x = cursor.fetchall()
return x
Document two
def city():
op = input("Enter < > or =: ")
population = input("Enter population: ")
pop = display.get_pop(op, population)
for p in pop:
print(pop)
I am getting the following error.
pymysql.err.ProgrammingError: (1064,......
Please help thanks
You can't do this. Parameterization works for values only, not operators or table names, or column names. You'll need to format the operator into the string. Do not confuse the %s placeholder here with Python string formatting; MySQL is awkward in that it uses %s for binding parameters, which clashes with regular Python string formatting.
The MySQL %s in a query string escapes the user input to protect against SQL Injection. In this case, I set up a basic test to see if the operation part submitted by the user was in a list of accepted operations.
def get_pop(op, pop):
query = "SELECT * FROM city WHERE Population {} %s" # Add a placeholder for format
with conn: # Where does this come from?
cursor = conn.cursor()
if op in ['=', '!=']:
cursor.execute(query.format(op), (pop,))
x = cursor.fetchall()
return x
You'll want to come up with some reasonable return value in the case that if op in ['=', '!='] is not True but that depends entirely on how you want this to behave.
After checking that op indeed contains either "<>" or "=" and that pop indeed contains a number you could try:
query = "SELECT * FROM city WHERE Population " + op + " %s";
Beware of SQL injection.
Then
cursor.execute(query, (pop))
I'm trying to loop over an MySQL query, however I can't get the variable to work. What am I doing wrong? The loop starts at line 10.
cur = db.cursor()
query = '''
Select user_id, solution_id
From user_concepts
Where user_id IN
(Select user_id FROM fields);
'''
cur.execute(query)
numrows = cur.rowcount
for i in xrange(0,numrows):
row = cur.fetchone()
# find all item_oid where task_id = solution_id for first gallery and sort by influence.
cur.execute('''
SELECT task_id, item_oid, influence
FROM solution_oids
WHERE task_id = row[%d]
ORDER BY influence DESC;
''', (i))
cur.fetchall()
error message:
File "james_test.py", line 114, in ''', (i))
File "/usr/lib64/python2.7/site-packages/MySQLdb/cursors.py", line 187, in execute
query = query % tuple([db.literal(item) for item in args])
TypeError: 'int' object is not iterable
cur.execute expect a tuple o dict for params but you gave (i) which is an int not a tuple. To make it a tuple add a comma (i,)
Here's how I would do this. You may not need to declare 2 cursors, but it won't hurt anything. Sometimes a second cursor is necessary because there could be a conflict. Notice how I demonstrate 2 different methods for looping the cursor data. One with the fetchall and one by looping the cursor. A third method could use fetch, but is not shown. Using a dictionary cursor is really nice, but sometimes you may want to use a standard non-dict cursor where values are retrieved only by their number in the row array. Also note the need to use a trailing comma in the parameter list when you have only 1 parameter. Because it expects a tuple. If you have more than 1 parameter, you won't need a trailing comma because more than 1 parm will be a tuple.
cursor1 = db.cursor(MySQLdb.cursors.DictCursor) # a dictcursor enables a named hash
cursor2 = db.cursor(MySQLdb.cursors.DictCursor) # a dictcursor enables a named hash
cursor1.execute("""
Select user_id, solution_id
From user_concepts
Where user_id IN (Select user_id FROM fields);
"""
for row in cursor1.fetchall():
user_id = row["user_id"]
solution_id = row["solution_id"]
cursor2.execute("""
SELECT task_id, item_oid, influence
FROM solution_oids
WHERE task_id = %s
ORDER BY influence DESC;
""", (solution_id,))
for data in cursor2:
task_id = data["task_id"]
item_oid = data["item_oid"]
influence = data["influence"]
Maybe try this:
a = '''this is the {try_}. try'''
i= 1
b = a.format(try_=i)
print b
You could even do:
data = {'try_':i}
b = a.format(**data)
sources:
python's ".format" function
Python string formatting: % vs. .format
I have troubles using a simple sql statement with the operator IN through pymssql.
Here is a sample :
import pymssql
conn = pymssql.connect(server='myserver', database='mydb')
cursor = conn.cursor()
req = "SELECT * FROM t1 where id in (%s)"
cursor.execute(req, tuple(range(1,10)))
res = cursor.fetchall()
Surprisingly only the first id is returned and I can't figure out why.
Does anyone encounter the same behavior ?
You're trying to pass nine ID values to the query and you only have one placeholder. You can get nine placeholders by doing this:
ids = range(1,10)
placeholders = ','.join('%s' for i in ids)
req = "SELECT * FROM t1 where id in ({})".format(placeholders)
cursor.execute(req, ids)
res = cursor.fetchall()
As an aside, you don't necessarily need a tuple here. A list will work fine.
It looks like you are only passing SELECT * FROM t1 where id in (1). You call execute with the tuple but the string only has one formatter. To pass all values, call execute like this:
cursor.execute(req, (tuple(range(1,10)),))
This will pass the tuple as first argument to the string to format.
EDIT: Regarding the executeone/many() thing, if you call executemany and it returns the last instead of the first id, it seems that execute will run the query 10 times as it can format the string with 10 values. The last run will then return the last id.
I am trying to query a mysql db from python but having troubles generating the query ebcasue of the wildcard % and python's %s. As a solution I find using ?, but when I run the following,
query = '''select * from db where name like'Al%' and date = '%s' ''', myDateString
I get an error
cursor.execute(s %'2015_05_21')
ValueError: unsupported format character ''' (0x27) at index 36 (the position of %)
How can i combine python 2.7 string bulding and sql wildcards? (The actual query is a lot longer and involves more variables)
First of all, you need to escape the percent sign near the Al:
'''select * from db where name like 'Al%%' and date = '%s''''
Also, follow the best practices and pass the query parameters in the second argument to execute(). This way your query parameters would be escaped and you would avoid sql injections:
query = """select * from db where name like 'Al%%' and date = %s"""
cursor.execute(query, ('2015_05_21', ))
Two things:
Don't use string formatting ('%s' % some_var) in SQL queries. Instead, pass the string as a sequence (like a list or a tuple) to the execute method.
You can escape your % so Python will not expect a format specifier:
q = 'SELECT foo FROM bar WHERE zoo LIKE 'abc%%' and id = %s'
cursor.execute(q, (some_var,))
Use the format syntax for Python string building, and %s for SQL interpolation. That way they don't conflict with each other.
You are not using the ? correctly.
Here's an example:
command = '''SELECT M.name, M.year
FROM Movie M, Person P, Director D
WHERE M.id = D.movie_id
AND P.id = D.director_id
AND P.name = ?
AND M.year BETWEEN ? AND ?;'''
*Execute the command, replacing the placeholders with the values of
the variables in the list [dirName, start, end]. *
cursor.execute(command, [dirName, start, end])
So, you want to try:
cursor.execute(query,'2015_05_21')