2017-08-08 91 views
0

我試圖將列表綁定到sqlalchemy中的原始SQL查詢中的參數。 This post建議與psycopg2這樣做的好方法如下。用pyodbc SQLAlchemy SQL參數列表替換

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 =

回答

0

這似乎是爲我工作:

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')] 
+0

是的,這似乎也適用於我。但上面的原始SQL查詢不起作用。任何想法爲什麼? –

+0

您可以使用['some_ids = [bindparam('id_1'),bindparam('id_2')]'](http://docs.sqlalchemy.org/en/latest/core/sqlelement.html#sqlalchemy.sql。如果想使用'executemany()',則可以顯式控制參數名稱。在你的例子中,你甚至不需要將手工形成的'params'傳遞給'execute()',因爲它們已經綁定在你的語句中。 –

+0

嗯我明白了。我想這是一種方法。但如果可能的話,我想編寫一個原始的SQL查詢並將一個列表作爲參數傳遞。 –