如何为IN()子句转义多个查询参数?

时间:2015-08-24 01:27:36

标签: python sql-server python-2.7 sqlalchemy

我正在尝试使用SELECT子句执行IN()查询,并让sqlalchemy执行 参数为我逃脱。我使用pyodbc作为我的数据库连接器。

这是我到目前为止编写的代码:

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

不幸的是,这失败并出现错误:

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

有没有什么方法可以让sqlalchemy转义整个参数列表并加入, 没有为列表中的每个项目手动添加:tableX占位符?

2 个答案:

答案 0 :(得分: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)
                    )

答案 1 :(得分:0)

出于好的理由,无法根据需要扩展参数列表。

如果你真的想创建一个 raw 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不存在,并且会引发异常。但是只查询我们可以关注的列(如上所示)就足够了。

相关问题