7

Environment

I am using Firebird database with SQLAlchemy as ORM wrapper.

Backgound

I know that by using in_ it is possible to pass the sales_id list in IN clause and get the result.

I have a use case where I must use textual sql.

Question

Here is my snippet,

conn.execute('select * from sellers where salesid in (:sales_id)', sales_id=[1, 2, 3] ).fetchall()

This always throws token unknown error

All I need is to pass the list of sales_id ([1, 2, 3]) to bind parameter (:sales_id) and get the result set.

5
  • Firebird itself doesn't support passing arrays or lists to a parameter in an IN-predicate, it only supports discrete values here. Which driver are you using, and does it provide special support for this? Commented Apr 23, 2019 at 12:37
  • I am using DP-API driver, which I think is the default. As @Ilja Everilä bindparam is the method as of now. Thanks, Mark for your effort. Commented Apr 23, 2019 at 14:56
  • DB-API is the Python specification for drivers, not a driver itself. Are you using FDB or pyfirebirdsql as your driver? Commented Apr 23, 2019 at 18:56
  • Sorry my bad, I am using FDB Commented Apr 24, 2019 at 3:33
  • Sometimes it may make sense to reverse the IN-condition and use SQL CONTAINING instead, if your list can grow truly long. See alternative approach at stackoverflow.com/a/43997801/976391 Commented Apr 24, 2019 at 10:43

1 Answer 1

10

If using a DB-API driver that does not provide special handling of tuples and lists for producing expressions for row constructors and IN predicates, you can use the somewhat new feature "expanding" provided by bindparam:

stmt = text('select * from sellers where salesid in :sales_id') 
stmt = stmt.bindparams(bindparam('sales_id', expanding=True))

conn.execute(stmt, sales_id=[1, 2, 3]).fetchall()

This will replace the placeholder sales_id on a per query basis by required placeholders to accommodate the sequence used as the parameter.

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

4 Comments

conn.execute(stmt, sales_id=[1, 2, 3]).fetchall() returns TypeError: get_bind() got an unexpected keyword argument 'sales_id'. By changing to conn.execute(stmt, {'sales_id': [1, 2, 3]} ).fetchall(), I am able to get what I needed. Thanks Ilja Everilä
What conn is? At least Engine.execute() accepts keyword arguments as arguments to query.
conn is the connection object

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.