gpt4 book ai didi

python - 动态 SQL WHERE 子句生成

转载 作者:IT王子 更新时间:2023-10-29 06:30:40 25 4
gpt4 key购买 nike

郑重声明,我使用的是 Python 和 SQLlite。我有一个可以生成我需要的 SQL 的工作函数,但它似乎不正确。

def daily(self, host=None, day=None):
sql = "SELECT * FROM daily WHERE 1"
if host:
sql += " AND host = '%s'" % (host,)
if day:
sql += " AND day = '%s'" % (day,)
return sql

稍后我可能需要添加多个列和条件。

有什么更好的主意吗?

编辑:看起来不对劲的是我正在从字符串动态构建 SQL。这通常不是最好的方法。 SQL 注入(inject)攻击,需要正确转义字符串。我不能使用占位符,因为一些值是 None 并且不需要在 WHERE 子句条件中。

最佳答案

真的不想使用字符串格式来包含值。通过 SQL 参数将其留给数据库 API。

使用参数你:

  • 让数据库有机会准备语句并重用查询计划以获得更好的性能。
  • 让自己不再为正确转义值而头疼(包括避免允许 SQL 转义和那些 SQL 注入(inject)攻击)。

自 SQLLite supports named SQL parameters ,我会返回一个语句和一个带有参数的字典:

def daily(self, host=None, day=None):
sql = "SELECT * FROM daily"
where = []
params = {}
if host is not None:
where.append("host = :host")
params['host'] = host
if day is not None:
where.append("day = :day")
params['day'] = day
if where:
sql = '{} WHERE {}'.format(sql, ' AND '.join(where))
return sql, params

然后将两者传递给cursor.execute():

cursor.execute(*daily(host, day))

SQL 生成变得复杂快速,您可能需要查看 SQLAlchemy core改为进行生成。

对于您的示例,您可以生成:

from sqlalchemy import Table, Column, Integer, String, Date, MetaData

metadata = MetaData()
daily = Table('daily', metadata,
Column('id', Integer, primary_key=True),
Column('host', String),
Column('day', Date),
)
from sqlalchemy.sql import select

def daily(self, host=None, day=None):
query = select([daily])
if host is not None:
query = query.where(daily.c.host == host)
if day is not None:
query = query.where(daily.c.day == day)
return query

query 对象可以应用额外的过滤器、排序、分组、用作其他查询的子选择、连接并最终发送以执行,此时 SQLAlchemy 会将其转换为 SQL fit针对您要连接的特定数据库。

关于python - 动态 SQL WHERE 子句生成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15496051/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com