简体   繁体   中英

Python + Postgres + psycopg2 : Composing a dynamic json query and dealing with quotes

I'm trying to compose a dynamic query involving a json column in Postgres using Python and the psycopg2 driver.

where_clause = ''
parameters = []

for key, v in (arguments):
    parameters.append(key)
    parameters.append(v)
    where_clause = where_clause + "data @> '{\"%s\":%s}' AND "

sql = u'select * from my_table where ' + where_clause + ' 1 = 1
db = connect(connection_string)
cur = db.cursor()
cur.execute(sql, tuple(parameters))
rows = cur.fetchall()
cur.close()
db.close()

When I do this, it has a problem with this '{\\"%s\\":%s}' .

psycopg2.ProgrammingError: syntax error at or near "favorite_topping"
LINE 1: select * from my_table where data @> '{"'favorite_topping'":'pepperoni'...

It doesn't like how I've arranged the quotes.

The problem appears to be how psycopg2 is chosing to insert quotes when it composes the final query.

Update

If I do this: where_clause = where_clause + "data @> \\"{%s:%s}\\" AND "

what I get is this:

where data @> "{'favorite_topping':'pepperoni'}"

and that fails because what Postgres wants are the quotes to be the other way around, like so:

where data @> '{"favorite_topping":"pepperoni"}'

Is there any way to get that to happen?

This is how the query parameterization works - the database driver determines the type of a query parameter to be a string and automatically puts quotes around the escaped value.

You can workaround it by using regular string formatting , but make sure to validate/sanitize/escape the query parameters yourself to avoid SQL injection attacks and problems with balanced quotes.

This should solve your problem:

from psycopg2.extras import Json
from psycopg2.extras import register_default_json
register_default_json(loads=lambda x: x)

query = u'select * from my_table where data @> %s;'
cur.execute(sql, Json({'favorite_topping':'pepperoni'})

Based largely on information in https://github.com/psycopg/psycopg2/issues/190 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM