26

I'm using Postgres 9 and Python 2.7.2 along with psycopg2 and am trying to insert an array of string values with properly escaped quotation marks. Sample:

metadata = {"Name": "Guest", "Details": "['One', 'Two', 'Three']"}

cur.execute("insert into meta values ('%s');" % metadata)

which throws the exception:

psycopg2.ProgrammingError: syntax error at or near "One"
LINE 1: "Details": "['One...
                      ^

I've also tried using Postgres' E to escape along with backslashes, but haven't found the correct combination yet. Ideas?

Growth Mindset
  • 1,135
  • 1
  • 12
  • 28

4 Answers4

35

You have to let psycopg do parameters binding for you: don't try to quote them yourself.

Psycopg automatically converts a python list of strings into a postgres array. Check https://www.psycopg.org/docs/usage.html#lists-adaptation

piro
  • 13,378
  • 5
  • 34
  • 38
6

When you want to insert an array into a postgreSQL DB via SQL you do it like this:

INSERT INTO tablename VALUES ('{value1,value2,value3}');

ATTENTION: You need the single quotes to surround the curly braces! So actually you're passing a String/Varchar of a special "array" grammar to the DB

If I enter your code into a python parser I get something like this:

'{'Name': 'Guest', 'Details': "['One', 'Two', 'Three']"}'

But PostgreSQL expects something like this:

'{"Name","Guest","Details",{"One","Two","Three"}}'

Check the manual on Arrays: http://www.postgresql.org/docs/9.0/static/arrays.html

So either you format the String according to the PostgreSQL "array-grammar" by writing a helper function or you use a library which does that for you.

das_weezul
  • 6,082
  • 2
  • 28
  • 33
1
def lst2pgarr(alist):
    return '{' + ','.join(alist) + '}'

pyarray = ['pippo', 'minni', 1, 2]

conn = psycopg2.connection (  HERE PUT YOUR CONNECTION STRING  )
c = conn.cursor()

c.execute('select ... where pgarray_attr = %r' % (lst2pgarr(pyarray))
c.execute('insert into tab(pgarray_attr) values (%r)' % (lst2pgarr(pyarray))
LittleEaster
  • 527
  • 7
  • 10
  • 3
    And what if pyarray contains a string with a comma, `'ciao,mondo'`? – piro Mar 03 '20 at 15:57
  • It would be a single object (out of topic). After 5 year my approaches has been changed. I guess that for instance you should declare if the comma-separated will be a 2nd dimension array or expanded, then a recursive split could be a fast-fix. Currently your suggestion is good: https://www.psycopg.org/docs/usage.html#lists-adaptation, now I like to use json datatype and, when I do not need transactions, I use postgRest.ogr – LittleEaster Mar 14 '20 at 14:48
-4

If you are going to dump the whole metadata as a string into the table, you can just do:

cur.execute("insert into meta values (%s);", (str(metadata),))
sayap
  • 6,169
  • 2
  • 36
  • 40