【问题标题】:Python SQL NOT LIKE , trying to exclude multiple valuesPython SQL NOT LIKE ,试图排除多个值
【发布时间】:2021-07-20 13:40:55
【问题描述】:

我有一个代码,如下所示,用户可以在其中列出过敏症列表。我希望我的代码提供一个食谱列表,将用户过敏列表中的成分排除在外。我做了一个测试代码,但无法弄清楚如何同时排除所有三种成分。

userallergy = conn.execute ('SELECT Allergies from User where userid = 4')
userallergy = userallergy.fetchall()
userallergy = userallergy[0][0].replace(" ","")
listallergy=list(userallergy.split(","))

listallergy = ["'%" + i.capitalize() + "%'" for i in listallergy]

print([listallergy])
query='SELECT RecipeName FROM Recipess where Ingredients Not LIKE {}'.format(listallergy[1])
print(query)

aller = conn.execute(query)
saferecipe = aller.fetchall()
print(saferecipe)

【问题讨论】:

  • 也许你应该试试正则表达式?

标签: python sql python-3.x database sqlite


【解决方案1】:

使用REGEXP 干净的方法(虽然不能直接使用,请查看Problem with regexp python and sqlite 的答案):

def regexp(expr, item):
    reg = re.compile(expr)
    return reg.search(item) is not None

conn.create_function("REGEXP", 2, regexp)

allergies = "|".join([i.capitalize() for i in listallergy])

print(allergies)
query='SELECT RecipeName FROM Recipess where Ingredients Not REGXP \'{}\''.format(allergies)
print(query)

一种简单的方法是通过AND 运算符加入所有语句(但正如@alexis 在 cmets 中提到的那样,它有自己的问题):

allergies = " AND ".join(["Ingredients Not LIKE '%" + i.capitalize() + "%'" for i in listallergy])

print(allergies)
query='SELECT RecipeName FROM Recipess where {}'.format(allergies)
print(query)

【讨论】:

  • 查询很好,但是当带有撇号的过敏名称到达时,这会变得很难看……如果你把它放在生产环境中,那就非常危险了。 SQL注入危险! (而且你不能像这里一样只使用带有可变长度列表的准备好的语句......)
【解决方案2】:

您可以使用 MySQL REGEX 'OR' 来排除所有三个。您的查询应如下所示:

query = f"SELECT RecipeName FROM `Recipess` WHERE Ingredients NOT REGEXP '{('|').join(listallergy)}'"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多