使用Python和SQLite3动态生成SQL查询

2024-04-26 21:05:03 发布

您现在位置:Python中文网/ 问答频道 /正文

以下是我的问题的概括:

考虑一下桌子

    ID    A    B    C
r1  1     1    0    1
.   .     .    .    .
.   .     .    .    .
.   .     .    .    .
rN  N     1    1    0

其中,A,B,C列包含01。我正在尝试编写一个python函数,它接受01的排列列表,生成一个将传递给SQLite3的查询,然后计算其中一个排列中包含A,B,C的记录数。

例如,如果我将下面的列表传递给我的函数permList = [[1,0,1],[1,0,0]],那么它将以[A,B,C]组合作为[1,0,1][1,0,0]来计算所有记录。

现在我是这样做的

def permCount(permList):
    SQLexpression = "SELECT Count(*) FROM Table WHERE "

    for i in range(len(permList)):
        perm = permList[i]
        SQLexpression += "(A=" + str(perm[0]) + " AND B=" + str(perm[1]) + 
                      " AND C=" + str(perm[2]) + ")"
        if i!=len(permList)-1:
            SQLexpression += " OR "

    *Execute SQLexpression and return answer*

现在这很好,但看起来有点像小提琴。有没有更好的方法动态生成输入长度未知的SQL查询?


Tags: and函数id列表len记录rnsqlite3
2条回答
def permCount(permList):
    condition = ' OR '.join(['(A=? AND B=? AND C=?)' 
                             for row in permList])
    sql = "SELECT Count(*) FROM Table WHERE {c}".format(
        c=condition)
    args = sum(permList, [])
    cursor.execute(sql, args)

使用parametrized SQL。这意味着不要插入具有字符串格式的值,而是使用placemarkers(例如?),然后将参数作为第二个参数提供给cursor.execute

这是更简单的代码,可以防止SQL injection

在主for循环中尝试这些更改,以使用pythons生成器并列出理解功能。

def permCount(permList):

SQLexpression = "SELECT Count(*) FROM Table WHERE "

for perm in permList:    # if you need the i for other reason, you could write:
                         # for i, perm in enumerate(permList)

    a, b, c = [str(_) for _ in perm]

    SQLexpression += "(A=" + a + " AND B=" + b + \
                  " AND C=" + c + ") OR "

SQLexpression = SQLexpression[:-4] + ";"   # Trim the last " OR "

相关问题 更多 >