I am working on a python script to connect to postgress databases using pygresql module. Below is the code
I am trying to run the query by passing tuple as parameter. query looks like this:
select sum(column1) from table_name where column2 in %s,(tuple,).
But I keep getting error "ERROR: syntax error at or near "%"".
import pg
tup_ids=('a','b','c')
def connection(cs):
"""
:param cs: cs is connection string
:return:
"""
conn=pg.connect(cs)
return conn
conn1 = connection(conn_string)
conn1.query('select sum(column1) from table_name where column2 in %s',(tup_ids,).
I am able to execute query using psycopg2 module. I am not able to pass tuple parameter for pg module. I have been pgresql documentation. I am not sure where I am doing wrong.
FYI: I need to use pygresql module only. Please help.
PyGreSQL "classic" (the pg module) supports PostgreSQL native parameters in its query
method, labelled $1
, $2
, ... Unfortunately, these accept only individual values, so you must construct a parameter list with as many values as your tuple first. This is very simple, though:
con = pg.connect(cs)
p_list = ','.join('$%d' % n for n in range(1, len(tup_ids) + 1))
q = con.query('select sum(column1) from table_name where column2 in (%s)' % p_list, tup_ids)
print(q.getresult())
Alternatively, you can use the query_formatted
method available in the DB
wrapper class of PyGreSQL classic (it is recommended to use that wrapper instead of raw connections anyway, because it adds a lot of convenience methods). This method uses Python formatting, so it must be used like this:
db = pg.DB(cs)
p_list = ','.join(['%s'] * len(tup_ids))
q = db.query_formatted(
'select sum(column1) from table_name where column2 in (%s)' % p_list, tup_ids)
print(q.getresult())
By using ANY
instead of IN
in your SQL statement, you can avoid creating a parameter list, and pass the values as a single list:
db = pg.DB(cs)
q = db.query_formatted(
'select sum(column1) from table_name where column2 = any(%s)', [list(tup_ids)])
print(q.getresult())
The PyGreSQL DB API 2 module (pgdb) also uses Python formatting and works similarly:
con = pgdb.connect(cs)
cur = con.cursor()
cur.execute('select sum(column1) from table_name where column2 = any(%s)', [list(tup_ids)])
print(cur.fetchone())
Note that we always passed the parameters separately. Do not be tempted to pass a query with Python-formatted values, as this is error prone and a safety issue ("SQL injection"), even if it looks simpler:
con = pg.connect(cs) # do NOT do this:
q = con.query('select sum(column1) from table_name where column2 in %s' % (tup_ids,))