如何在asyncpg预处理语句游标中传入列表等集合类型参数
解决asyncpg预处理语句传递可变数量列表参数的问题
嘿,这个问题其实很好解决——asyncpg的cursor()方法支持用Python的解包操作符来传递列表形式的参数,刚好适配你这种参数数量不确定的场景!
核心解决方案
你只需要用*操作符把参数列表直接解包传递给cursor()方法就行,不用再手动逐个写params[0], params[1]。比如把原来的:
async for record in stmt.cursor(params[0], params[1]):
改成:
async for record in stmt.cursor(*params):
修改后的完整代码
我还帮你优化了连接的管理(用async with自动关闭连接,避免漏关的问题),调整后的代码如下:
async def execute_ps(dsn): # 用async with自动管理连接,无需手动close async with await asyncpg.connect(dsn) as conn: sql_query = """select * from table1 where id = $1 and name=$2""" params = [var1, var2] stmt = await conn.prepare(sql_query) result = [] try: async with conn.transaction(): # 这里用*解包列表参数 async for record in stmt.cursor(*params): print(record) result.append(record) except Exception as e: print(f"exception: {e}") return result
拓展:如果SQL占位符数量也需要动态生成
要是你的查询场景是参数数量完全不确定(比如IN子句),还可以动态生成SQL里的占位符,比如:
# 假设params是一个不确定长度的id列表 params = [1, 3, 5, 7] # 动态生成$1, $2, $3, $4这样的占位符 placeholders = ', '.join([f"${i+1}" for i in range(len(params))]) sql_query = f"""select * from table1 where id in ({placeholders})""" stmt = await conn.prepare(sql_query) # 同样用*解包参数 async for record in stmt.cursor(*params): # 处理记录
这样不管参数有多少个,都能完美适配预处理语句的要求啦!
内容的提问来源于stack exchange,提问作者Atihska
相关产品推荐
相关产品推荐

