28

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?

1
  • What error do you get with "[\'One\', \'Two\', \'Three\']"? Commented Jul 28, 2011 at 1:28

4 Answers 4

36

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

Sign up to request clarification or add additional context in comments.

5 Comments

Ah I missed the slight format change. Using cur.execute("insert into meta values %s", metadata) worked for me. Thank you very much.
Answer link is dead, future searchers can see "Link adaptation" section over here: psycopg.org/docs/usage.html. Basically you need to pass the Python list like so: cur.execute("SELECT * FROM data WHERE id = ANY(%s);", (yourList,))
+1 to @EnglishRain's solution. Just linking the exact section of the docs: psycopg.org/docs/usage.html#adapt-list
Thank you, link fixed
@EnglishRain solution works for a list.
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.

Comments

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

2 Comments

And what if pyarray contains a string with a comma, 'ciao,mondo'?
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: 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
-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),))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.