我正在尝试使用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
占位符?
答案 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
不存在,并且会引发异常。但是只查询我们可以关注的列(如上所示)就足够了。