您真的不想使用字符串格式来包含值。通过 SQL 参数将其留给数据库 API。
使用参数你:
- 让数据库有机会准备语句并重用查询计划以获得更好的性能。
- 省去正确转义值的麻烦(包括避免允许 SQL 转义和那些 SQL 注入攻击)。
由于 SQLLite支持命名 SQL 参数,我将返回一个语句和一个带参数的字典:
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 核心来代替生成。
对于您的示例,您可以生成:
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。