2015-08-24 24 views
0

我正在嘗試使用IN()子句執行SELECT查詢,並讓sqlalchemy執行 參數轉義給我。我使用pyodbc作爲我的數據庫連接器。如何轉義IN()子句的多個查詢參數?

這是迄今爲止我所編寫的代碼:

tables = ['table1', 'table2', ... ] 
sql = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME IN(:tables)" 
result = session.execute(sql, {"tables": tables}) 

Unfortunatenly失敗與錯誤:

sqlalchemy.exc.ProgrammingError: (pyodbc.ProgrammingError) ('Invalid parameter type. param-index=0 param-type=list', 'HY105') 

有沒有什麼方法可以讓我有SQLAlchemy中逃脫的參數的整個列表和加入, 而不手動爲列表中的每個項目添加:tableX佔位符?

回答

0

嘗試這樣的事情....

DECLARE @string Varchar(100) = 'Table1,table2,table3' 

    declare @xml xml 
    set @xml = N'<root><r>' + replace(@string,',','</r><r>') + '</r></root>' 


SELECT * FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME IN( select 
        r.value('.','varchar(max)') as item 
        from @xml.nodes('//root/r') as records(r) 
        ) 
0

爲了獲得良好的原因,是不可能的,因爲你希望擴大參數列表。

如果你真的想創建一個原料SQL query,那麼你可以枚舉列表和動態創建查詢:

vals = {"param{}".format(i): table for i, table in enumerate(tables)} 
keys = ", ".join([":{}".format(k) for k in vals]) 
sql = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME IN ({keys})".format(keys=keys) 
result = session.execute(sql, vals) 

for tbl in result: 
    print(tbl) 

但是你可以問sqlalchemy爲你做到這一點。在這裏,我們做INFORMATION_SCHEMA.tables視圖的映射,並使用sqlalchemy工具集進行查詢:

# definition (done just once) 
class ISTable(Base): 
    __tablename__ = 'tables' 
    __table_args__ = {'schema': 'INFORMATION_SCHEMA'} 
    _fake_id = Column(Integer, primary_key=True) 
    table_catalog = Column(String) 
    table_schema = Column(String) 
    table_name = Column(String) 
    table_type = Column(String) 

# actual usage 
result = session.query(
    ISTable.table_catalog, ISTable.table_schema, 
    ISTable.table_name, ISTable.table_type, 
).filter(
    ISTable.table_name.in_(tables)) 

for tbl in result: 
    print(tbl) 

有一個問題:您無法查詢整個映射類(像這樣query(ISTable)),因爲primary_key不存在,將會引發異常。但只查詢我們可以查看的列(如上所示)就足夠了。