1
cursor.execute(text("SELECT * FROM pnl WHERE type IN (:types)"))

作品。

以下测试:

cursor.execute(text("SELECT * FROM pnl WHERE type IN (:types)"), types=[2, 3, 5, 6, 7])
cursor.execute(text("SELECT * FROM pnl WHERE type IN (:types)"), types=tuple([2, 3, 5, 6, 7]))
cursor.execute(text("SELECT * FROM pnl WHERE type IN (:types)"), types=list([2, 3, 5, 6, 7]))

抛出异常:

(Background on this error at: https://sqlalche.me/e/14/f405) - Traceback (most recent call last):
  File "/Git/argus-periodic/venv/lib/python3.9/site-packages/pg8000/legacy.py", line 252, in execute
    self._context = self._c.execute_unnamed(
  File "/Git/argus-periodic/venv/lib/python3.9/site-packages/pg8000/core.py", line 649, in execute_unnamed
    self.handle_messages(context)
  File "/Git/argus-periodic/venv/lib/python3.9/site-packages/pg8000/core.py", line 767, in handle_messages
    raise self.error
pg8000.exceptions.DatabaseError: {'S': 'ERROR', 'V': 'ERROR', 'C': '22P02', 'M': 'invalid input syntax for type integer: "{2,3,5,6,7}"', 'F': 'numutils.c', 'L': '323', 'R': 'pg_strtoint32'}

那么如何传递一个列表以在 sql alchemy 的 IN 查询中使用。

4

1 回答 1

0

pg8000 和 SQLAlchemy 对IN子句的处理都有一些特殊之处,需要在这里考虑。

pg8000要求 IN查询采用这种形式

SELECT col FROM tbl WHERE col IN (SELECT(unnest(CAST(:params) AS integer[])))

SQLAlchemy 要求我们在用作子句的目标时将参数标记为扩展。IN

所以最终的 SQLAlchemy 代码看起来像这样:

values = {'types': [2, 3, 5, 6, 7]}
q = sa.text('select * from pnl where type in (select(unnest(cast(:types as integer[]))))')
q.bindparams(sa.bindparam('types', expanding=True))

with engine.connect() as conn:
    result = conn.execute(q, values)
    # Do stuff with result.
于 2021-11-29T18:48:30.180 回答