Select within another select syntax in Python and MySQL - python

I have mysql select command that counts the number of rows return based on two select commands as follows:
SELECT count(*)-1 as elmlen FROM invertedindextb WHERE
dewId IN
(SELECT dewId FROM invertedindextb WHERE eTypeId = ? and trm = ?)
and docId IN
(SELECT docId FROM invertedindextb WHERE eTypeId = ? and trm = ?)
I wrote a python function that implements the above select command as follows:
def lenOfNode (self, cursor, eTypeId , trm):
sql = """ SELECT COUNT(*)-1 AS LEN FROM invertedindextb WHERE \
dewId IN ("SELECT dewId FROM invertedindextb WHERE eTypeId = '%d' and trm = '%s' %(eTypeId,trm)") \
and docId IN ("SELECT docId FROM invertedindextb WHERE eTypeId = '%d' and trm = '%s' %(eTypeId,trm)") """
cursor.execute(sql)
results = cursor.fetchone()
print results[0]
return results[0]
Although the function run ( but computes wrong answer), I am not sure whether the syntax of the select command is correct in python.
Can somebody help me with correct syntax for the select statement

Do not use \ in the sql string, you started it with triple quote thus all new lines are ok already.
You placed your arguments to the % operator into the string, turning them into literal text. Try to print your query before executing it, like
def lenOfNode (self, cursor, eTypeId , trm):
sql = """ SELECT COUNT(*)-1 AS LEN FROM invertedindextb WHERE \
dewId IN ("SELECT dewId FROM invertedindextb WHERE eTypeId = '%d' and trm = '%s' %(eTypeId,trm)") \
and docId IN ("SELECT docId FROM invertedindextb WHERE eTypeId = '%d' and trm = '%s' %(eTypeId,trm)") """
print "My real sql query was:\n", sql
cursor.execute(sql)
results = cursor.fetchone()
print results[0]
return results[0]
Your mistace is that "aaa %d" % (10,) string (which should give "aaa 10") is turned into '''"aaa %d" % (10,)''' (and will give '"aaa %d" % (10,)'), which is not what you intended. For me, the best way to develop an eye to such things was to try all suspicious part of my code in IPython console with %ed magick command.
And using %s in sql query introduces direct vulnerability - sql injection - in your code.

I forget to add the "and" operator between the first select command and second in the where clause so on adding the and operator as follows the def runs and return correct result:
sql = """ SELECT (COUNT(*)-1) AS LEN FROM invertedindextb WHERE
(dewId IN (SELECT dewId FROM invertedindextb WHERE eTypeId = '%d' and trm = '%s') and
docId IN (SELECT docId FROM invertedindextb WHERE eTypeId = '%d' and trm = '%s')) """ %(eTypeId,trm,eTypeId,trm)

Related

Query a mysql table for a dynamic column name and its value in python?

I want to search a mysql table for rows where the specified column has a particular value. For example, given the input string memory=2048 it will search for the rows that have "2048" as the value of memory column and it will print them.
This is code that I have tried but it print outs nothing.
input = input()
tag = input.split("=")
desc = tag[1]
tag = tag[0]
mycursor = mydb.cursor()
sql = "(SELECT * FROM comp WHERE %s LIKE %s)"
val = (tag, desc)
mycursor.execute(sql, val)
res = mycursor.fetchall()
for x in res:
print(x)
Secondly I tried this code to see where is the problem :
input = input()
tag = input.split("=")
desc = tag[1]
tag = tag[0]
mycursor = mydb.cursor()
sql = "(SELECT * FROM comp WHERE memory LIKE '2048')"
mycursor.execute(sql)
res = mycursor.fetchall()
for x in res:
print(x)
It gives the desired output. So my problem is when I am trying to get the column name with %s it comes as 'memory' and It couldn't finds it, since the name of the column is memory. Is there a way to get rid of the '' chars ?
confirmation of inputs
Looking at the mysql.connector's execute() documentation it appears to use %s as placeholders for bind parameters.
So your execute("SELECT * FROM comp WHERE %s LIKE %s", ("memory", "2048")) call ends up running like the following SQL:
SELECT * FROM comp WHERE 'memory' LIKE '2048'
obviously returning 0 rows.
You need to put the literal column name into the query text before invoking execute():
sql = "SELECT * FROM comp WHERE %s LIKE %s" % (tag, "%s")
# => "SELECT * FROM comp WHERE memory LIKE %s"
mycursor.execute(sql, (desc, ))

Error in using variables in SQL statement in Python?

I have the following Python code:
cursor = connection.cursor()
a = "C6DE6778-5956-48D4-BED6-5A2A37BBB123"
SQLCommand = ("""SELECT *
FROM Table
WHERE Table.ENUM = ?
""", a)
results = cursor.execute(SQLCommand)
The following error is returned:
TypeError: string or integer address expected instead of tuple instance
The way you constructed the sqlcommand is incorrect. Pass the parameter when you execute.
a = "C6DE6778-5956-48D4-BED6-5A2A37BBB123"
SQLCommand = """SELECT *
FROM Table
WHERE Table.ENUM = ?
"""
results = cursor.execute(SQLCommand,(a,))
SQLCommand is a tuple in your case. .execute() expects sql statement as the first argument. To rectify the error, you can do something like this :
cursor = connection.cursor()
a = "C6DE6778-5956-48D4-BED6-5A2A37BBB123"
SQLCommand = """SELECT *
FROM Table
WHERE Table.ENUM = '%s'
""" % a
results = cursor.execute(SQLCommand)
Alternatively, you can format you SQL statement string like this :
SQLCommand = """SELECT *
FROM Table
WHERE Table.ENUM = '{}'
""".format(a)
Or you can pass a as an optional parameter to .execute() like this :
cursor = connection.cursor()
a = "C6DE6778-5956-48D4-BED6-5A2A37BBB123"
SQLCommand = """SELECT *
FROM Table
WHERE Table.ENUM = ?
"""
print(SQLCommand, a)
You can refer to the documentation for more understanding on this.

Use a python dictionary to insert into mysql

I am trying to take the data from a dictionary (the example is simplified for readability) and insert it into a mysql database.
I have the following piece of code.
import pymysql
conn = pymysql.connect(server, user , password, "db")
cur = conn.cursor()
ORFs={'E7': '562', 'E6': '83', 'E1': '865', 'E2': '2756 '}
table="genome"
cols = ORFs.keys()
vals = ORFs.values()
sql = "INSERT INTO %s (%s) VALUES(%s)" % (
table, ",".join(cols), ",".join(vals))
print sql
print ORFs.values()
cur.execute(sql, ORFs.values())
cur.close()
conn.close()
the print sql statement returns
INSERT INTO genome (E7,E6,E1,E2) VALUES(562,83,865,2756 )
when I type this directly into the mysql command line, the mysql command works. But when I run the python script I get an error:
<type 'exceptions.TypeError'>: not all arguments converted during string formatting
args = ('not all arguments converted during string formatting',)
message = 'not all arguments converted during string formatting'
As always, any suggestions would be highly appreciated.
The previous answer doesn't work for non string dictionary value. This one is a revised version.
format_string = ','.join(['%s'] * len(dict))
self.db.set("""INSERT IGNORE INTO listings ({0}) VALUES ({1})""".format(", ".join(dict.keys()),format_string),
(dict.values()))
sql = "INSERT INTO %s (%s) VALUES(%s)" % (
table, ",".join(cols), ",".join(vals))
This SQL includes values and cur.execute(sql, ORFs.values()) has values, too.
So, it should be cur.execute(sql).
In my case, I will skip null columns.
data = {'k': 'v'}
fs = ','.join(list(map(lambda x: '`' + x + '`', [*data.keys()])))
vs = ','.join(list(map(lambda x: '%(' + x + ')s', [*data.keys()])))
sql = "INSERT INTO `%s` (%s) VALUES (%s)" % (table, fs, vs)
count = cursor.execute(sql, data)

Python: how to pass string to postgres command using psycopg2

I have a problem passing a string to a query in python for postgresql. In particular I have the following script that works perfectly:
y = 'test'
for i in un:
crs = conn.cursor()
query = """
select *
FROM test
WHERE test.vin_id = %s
;"""
s_id = i
crs.execute(query,[s_id])
s_out = crs.fetchall()
but if I change test with the variable y it gives me an error.
for i in un:
crs = conn.cursor()
query = """
select *
FROM %s
WHERE %s.vin_id = %s
;"""
s_id = i
crs.execute(query,[y,y,s_id])
s_out = crs.fetchall()
ProgrammingError: syntax error at or near "'test'"
LINE 3: FROM 'test'
Unfortunately it does not work and I have the same problem when I try to put sentences in the middle, for instance:
query1 = """
SELECT *
FROM test1
WHERE %s LIKE '%' || vin_id || '%'
;"""
crs1 = conn.cursor()
crs1.execute(query1, [s_id])
You can use AsIs:
from psycopg2.extensions import AsIs
for i in un:
crs = conn.cursor()
query = """
select *
FROM %s
WHERE %s.vin_id = %s
;"""
s_id = i
crs.execute(query,[AsIs(y),AsIs(y),s_id])
s_out = crs.fetchall()

Python and sqlite trouble

I can't show the data from database sqlite in python.
connection = sqlite3.connect('db')
connection.cursor().execute('CREATE TABLE IF NOT EXISTS users ( \
id TEXT, \
name TEXT, \
avatar TEXT \
)')
# In cycle:
query = 'INSERT INTO users VALUES ("' + str(friend.id) + '", "' + friend.name + '", "' + friend.avatar +'" )'
print query
connection.cursor().execute(query)
connection.commit()
# After cycle
print connection.cursor().fetchall()
Sample output of query variable:
INSERT INTO users VALUES ("111", "Some Name", "http://avatar/path" )
In result, fetchall returns empty tuple. Why?
UPD
Forgotten code:
connection.cursor().execute('SELECT * FROM users')
connection.cursor().fetchall()
→
[]
INSERT does not return data. To get the data back out, you'll have to issue a SELECT statement.
import sqlite3
con = sqlite3.connect("db")
con.execute("create table users(id, name, avatar)")
con.execute("insert into users(id, name, avatar) values (?, ?, ?)", (friend.id, friend.name, friend.avatar))
con.commit()
for row in con.execute("select * from users")
print row
con.close()
Because the create table string as displayed is syntactically invalid Python, as is the insert into string.
Actually, the answer to your first question is: because you use different cursors.
connection.cursor() creates a new cursor in the connection you created before. fetchall() gives you the results of the query you executed before in that same cursor. I.e. what you did was this:
# After cycle
cursor1 = connection.cursor()
cursor1.execute('SELECT * FROM users')
cursor2 = connection.cursor()
cursor2.execute("")
cursor2.fetchall()
What you should have done was this:
# After cycle
cursor = connection.cursor()
cursor.execute('SELECT * FROM users')
print cursor.fetchall()

Categories

Resources