2016-11-04 37 views
1

我想用一个IN运算符构造一个SQL语句,该运算符可以处理任意长度的列表。我正在与python,pandas和sqlalchemy合作。使用python中的sqlalchemy和pandas构建一个可变长度的SQL查询

例如,如果我想执行的查询是

SELECT * FROM users WHERE age IN (25, 26, 27)" 

我曾尝试:

import pandas as pd 
from sqlalchemy.sql import text 

ages = (25, 26, 27) 
query = text("SELECT * FROM users WHERE age IN (:x)") 
df = pd.read_sql_query(query, conn, params={"x":ages}) 

但是这会导致错误。我如何正确构建查询?如果IN运营商的列表中只有一个值,即ages = tuple(25),我希望解决方案能够运行。

+0

您可能想试试[this](http://stackoverflow.com/a/26184603/5741205)。 PS它不适合我的SQLite和目前我无法检查它对其他SQL DB ... – MaxU

回答

1

一个解决方案是使用python的字符串join()方法。

的例子就是阅读:

import pandas as pd 
from sqlalchemy.sql import text 

ages = (25, 26, 27) 
ages = (str(n) for n in ages) 
ages = ','.join(ages) 
query = text("SELECT * FROM users WHERE age IN (:x)") 
df = pd.read_sql_query(query, conn, params={"x":ages}) 
+1

这似乎不正确。它的结果是'年龄在('25,26,27')'而不是'年龄在(25,26,27)'。 – univerio

1

考虑一个动态SQL字符串建立使用字典修真参数占位符和动态辞典的构建。下面假设您的RDMS是带冒号命名参数的SQLite:

import pandas as pd 
from sqlalchemy.sql import text 

ages = (25, 26, 27) 
placeholders = ', '.join([':param'+str(i) for i in range(len(ages))]) 
paramdict = {'param'+str(i): ages[i] for i in range(len(ages))} 

query = text("SELECT * FROM users WHERE age IN ({})".format(placeholders)) 
# SELECT * FROM users WHERE age IN (:param0, :param1, :param2) 

df = pd.read_sql_query(query, conn, params=paramdict)