【问题标题】:SQLAlchemy SQL parameter list substitution with pyodbcSQLAlchemy SQL 参数列表替换与 pyodbc
【发布时间】:2017-08-08 19:48:43
【问题描述】:

我正在尝试将列表绑定到 sqlalchemy 中原始 SQL 查询中的参数。 This post 建议使用psycopg2 这样做的好方法,如下所示。

some_ids = [1, 2, 3, 4]
query = "SELECT * FROM my_table WHERE id = ANY(:ids);"
engine.execute(sqlalchemy.sql.text(query), ids=some_ids)

但是,这似乎不适用于 SQL Serverpyodbc 的环境。只添加了一个 "?" 而不是 4 个。

sqlalchemy.exc.ProgrammingError: (pyodbc.ProgrammingError) 
('Invalid parameter type. param-index=0 param-type=tuple', 'HY105') 
[SQL: 'SELECT * FROM my_table WHERE id = ANY(?);'] [parameters: ((1, 2, 3, 4),)]

有什么办法可以使这个工作吗?如果可能,我想避免使用manually creating placeholders

sqlalchemy 版本=1.0.13,pyodbc 版本=4.0.16

【问题讨论】:

    标签: python sql-server sqlalchemy pyodbc


    【解决方案1】:

    这似乎对我有用:

    from sqlalchemy import create_engine
    from sqlalchemy.sql import table, column, select, literal_column
    engine = create_engine('mssql+pyodbc://SQLmyDb')
    cnxn = engine.connect()
    some_ids = [2, 3]
    sql = select([literal_column('*')]).where(column('ID').in_(some_ids)).select_from(table('People'))
    print(sql)
    print('')
    params = {":ID_" + str(x+1): some_ids[x] for x in range(len(some_ids))}
    rows = cnxn.execute(sql, params).fetchall()
    print(rows)
    

    打印生成的 SQL 语句,然后是查询结果

    SELECT * 
    FROM "People" 
    WHERE "ID" IN (:ID_1, :ID_2)
    
    [(2, 'Anne', 'Elk'), (3, 'Gord', 'Thompson')]
    

    【讨论】:

    • 是的,这似乎也对我有用。但是上面的原始 SQL 查询不起作用。知道为什么吗?
    • 如果想使用executemany(),可以使用some_ids = [bindparam('id_1'), bindparam('id_2')] 来显式控制参数名称。在您的示例中,您甚至不需要将手动形成的params 传递给execute(),因为它们已经绑定在您的语句中。
    • 嗯,我明白了。我想这是一种方式。但如果可能的话,我想编写一个原始 SQL 查询并将一个列表作为参数传递。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多