6

Suppose you have a table "foo" in postgres with column name "col (parens) name". The psql command

INSERT INTO "foo" ("col (parens) name") VALUES ('bar');

works just fine. However, if I try to do the same using sqlalchemy (version 0.9.7), the resulting python code fails:

conn = sqlalchemy.create_engine('postgresql://name:password@host:port/database')
meta = sqlalchemy.schema.MetaData()
meta.reflect(bind=conn)
foo = meta.tables['foo']
vals = [{'col (parens) name': 'hi'}, {'col (parens) name': 'bye'}]
conn.execute(foo.insert(values=vals))

This does not work, giving the following error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sqlalchemy/engine/base.py", line 729, in execute
    return meth(self, multiparams, params)
  File "sqlalchemy/sql/elements.py", line 321, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "sqlalchemy/engine/base.py", line 826, in _execute_clauseelement
    compiled_sql, distilled_params
  File "sqlalchemy/engine/base.py", line 957, in _execute_context
    context)
  File "sqlalchemy/engine/base.py", line 1162, in _handle_dbapi_exception
    util.reraise(*exc_info)
  File "sqlalchemy/engine/base.py", line 950, in _execute_context
    context)
  File "sqlalchemy/engine/default.py", line 436, in do_execute
    cursor.execute(statement, parameters)
KeyError: 'col (parens'

Apparently the sqlalchemy method to bind db parameters is running into trouble with python string interpolation. Any suggestions for a workaround?

1
  • SQLA 2.0, modulo some syntactic differences, seems to handle this case correctly. Commented May 22 at 17:15

1 Answer 1

9

Add paramstyle="format" to the create_engine call. It will change the way the query values are inserted to the query in a way that it won't crash on closing brackets.

conn = sqlalchemy.create_engine(
    'postgresql://name:password@host:port/database',
     paramstyle="format"
)
Sign up to request clarification or add additional context in comments.

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.