Python: how to pass string to postgres command using psycopg2 - python

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()

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, ))

How to pass string without quotes in cassandra parameter of .execute method

My query:
SELECT *
FROM employee.emp_details
WHERE id = 7
This is my code
from cassandra.cluster import Cluster
HOST = ['10.107.2.123']
PORT = '9042'
cluster = Cluster(HOST, PORT)
session = cluster.connect()
val = 'FROM'
rows = session.execute('''SELECT * %s employee.emp_details WHERE id = %s''', (val, 7))
This is the error that I am getting:
Traceback (most recent call last):
File "/home/sachhya/Documents/Example/ex.py", line 9, in
rows = session.execute('''SELECT * %s employee.emp_details WHERE id = %s''', (val, 7))
File "/usr/local/lib/python3.6/dist-packages/cassandra/cluster.py", line 2134, in execute
return self.execute_async(query, parameters, trace, custom_payload, timeout, execution_profile, paging_state).result()
File "/usr/local/lib/python3.6/dist-packages/cassandra/cluster.py", line 4026, in result
raise self._final_exception
cassandra.protocol.SyntaxException:
I believe that my query string is something made like that after parameter bind. SELECT * 'FROM' employee.emp_details WHERE id = 7
Please help I need to use 'val' variable to bind in my query string.
Technically, you don't have to bind the FROM in your query. Use string formatting in this case:
rows = session.execute('''SELECT * {} employee.emp_details WHERE id = %s'''.format(val), (7,))
from cassandra.cluster import Cluster
HOST = ['10.107.2.123']
PORT = '9042'
cluster = Cluster(HOST, PORT)
session = cluster.connect()
val = 'FROM'
query = 'SELECT * {} employee.emp_details WHERE id = {}'.format(val, 7)
# or query = ('SELECT * %s employee.emp_details WHERE id = %s' % (a, 7))
rows = session.execute(query)
output from terminal:
>>> query = ('SELECT * %s employee.emp_details WHERE id = %s' % (a, 7))
>>> query
'SELECT * FROM employee.emp_details WHERE id = 7'
>>> query = 'SELECT * {} employee.emp_details WHERE id = {}'.format(a, 7)
>>> query
'SELECT * FROM employee.emp_details WHERE id = 7'
Let me show you the power of prepared statements.
from cassandra.cluster import Cluster
HOST = ['10.107.2.123']
PORT = '9042'
cluster = Cluster(HOST, PORT)
session = cluster.connect()
val=7
query="SELECT * employee.emp_details WHERE id = ?"
prepared_query=session.prepare(prepared_query)
results=session.execute(prepared_query,(val))
print results
Use Prepared Statements to when you have to iterate through variables in query.
Visit: Prepared Statements Docs

Python code not creating tables on the database but able to query the results postgres

My usecase is to write create a temp table in the postgres database and fetch records from it and insert into a different table.
The code i used is:
import psycopg2
import sys
import pprint
from __future__ import print_function
from os.path import join,dirname,abspath
import xlrd
import os.path
newlist = []
itemidlist = []
def main():
conn_string = "host='prod-dump.cvv9i14mrv4k.us-east-1.rds.amazonaws.com' dbname='ebdb' user='ebroot' password='*********'"
# print the connection string we will use to connect
# print "Connecting to database" % (conn_string)
# get a connection, if a connect cannot be made an exception will be raised here
conn = psycopg2.connect(conn_string)
# conn.cursor will return a cursor object, you can use this cursor to perform queries
cursor = conn.cursor()
dealer_id = input("Please enter dealer_id: ")
group_id = input("Please enter group_id: ")
scriptpath = os.path.dirname('__file__')
filename = os.path.join(scriptpath, 'Winco - Gusti.xlsx')
xl_workbook = xlrd.open_workbook(filename, "rb")
xl_sheet = xl_workbook.sheet_by_index(0)
print('Sheet Name: %s' % xl_sheet.name)
row=xl_sheet.row(0)
from xlrd.sheet import ctype_text
print('(Column #) type:value')
for idx, cell_obj in enumerate(row):
cell_type_str = ctype_text.get(cell_obj.ctype, 'unknown type')
#print('(%s) %s %s' % (idx, cell_type_str, cell_obj.value))
num_cols = xl_sheet.ncols
for row_idx in range(0, xl_sheet.nrows): # Iterate through rows
num_cols = xl_sheet.ncols
id_obj = xl_sheet.cell(row_idx, 1) # Get cell object by row, col
itemid = id_obj.value
#if itemid not in itemidlist:
itemidlist.append(itemid)
# execute our Query
'''
cursor.execute("""
if not exists(SELECT 1 FROM model_enable AS c WHERE c.name = %s);
BEGIN;
INSERT INTO model_enable (name) VALUES (%s)
END;
""" %(itemid,itemid))
'''
cursor.execute("drop table temp_mbp1")
try:
cursor.execute("SELECT p.model_no, pc.id as PCid, g.id AS GROUPid into public.temp_mbp1 FROM products p, \
model_enable me, products_clients pc, groups g WHERE p.model_no = me.name \
and p.id = pc.product_id and pc.client_id = %s and pc.client_id = g.client_id and g.id = %s"\
% (dealer_id,group_id)
except (Exception, psycopg2.DatabaseError) as error:
print(error)
cursor.execute("select count(*) from public.temp_mbp1")
# retrieve the records from the database
records = cursor.fetchall()
# print out the records using pretty print
# note that the NAMES of the columns are not shown, instead just indexes.
# for most people this isn't very useful so we'll show you how to return
# columns as a dictionary (hash) in the next example.
pprint.pprint(records)
if __name__ == "__main__":
main()
The try except block in between the program is not throwing any error but the table is not getting created in the postgres database as i see in the data admin.
The output shown is:
Please enter dealer_id: 90
Please enter group_id: 13
Sheet Name: Winco Full 8_15_17
(Column #) type:value
[(3263,)]
Thanks,
Santosh
You didn't commit the changes, so they aren't saved in the database. Add to the bottom, just below the pprint statement:
conn.commit()

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.

Select within another select syntax in Python and MySQL

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)

Categories

Resources