2012-12-05 75 views
0

当我想要做IN查询与MySQLdb,我喜欢写东西更好的办法做到`IN`查询与Python MySQLdb的

ids = [1,2,3,4,5] # in most cases, this is passed in as a parameter 
placeholder = ",".join(["%s"] % len(ids)) 
cursor.execute("SELECT * FROM a_table WHERE id IN (%s)" % placeholders, 
       ids) 

这是非常麻烦无处不在重复这一点。

我已阅读MySQLdb的使用说明书,但未发现任何相关内容。

所以我想知道其他人怎么做到这一点? MySQLdb是否提供了一个没有记录的更好的方法?

+0

为什么你有'LEN(IDS)'?它不应该是'placeholder =“,”。join(ids)'? –

+0

@YevgenYampolskiy我用它在第二行创建了一个字符串,如“%s,%s,%s”。后来,我将这个字符串插入到'sql'语句中,并将列表'ids'作为第二个参数。 – satoru

回答

0

如果你愿意尝试SQLAlchemy(我更熟悉的烧瓶SQLAlchemy的,所以你可能需要稍微修改代码),可以简化本查询到的东西:

class a_table(db.Model): 
    __tablename__ = 'a_table' 
    __table_args__ = { 
     'autoload': True, 
     'autoload_with': db.engine 
    } 

ids = [1,2,3,4,5] 
results = a_table.query.filter(a_table.id.in_(ids)).all() 
0

上面的方法似乎是最好的方法,因为如您所知,参数化值将转换为文字。如果您多次进行此操作,我唯一(无可否认的)建议就是在转换过程中完成一项功能。并不理想,但很少绕过MySQLdb提供的内置消毒功能,我似乎无法找到另一种方法来处理它(但并不是说没有其他方法)。另外,你可能已经想到了这一点已经:)

def InQuery(query, vals): 
    # Would likely have to be adjusted to handle more complex/compound cases 
    return query % ', '.join(['%s'] * len(vals)) 

然后执行类似的疑问:

ids = [1,2,3,4,5] 
cursor.execute(InQuery(query, ids), ids) 
+0

我认为用这种方式格式化'SQL'语句可能有被SQL注入攻击的风险。 – satoru

+0

@ Satori.Logic在第一个例子中,是的:)第二个例子(使用实际的查询结构)利用了MySQLdb内置的参数清理(我现在无法测试:)。 – RocketDonkey

+0

@ Satoru.Logic对不起,我确切地看到你现在在说什么(道歉 - 应该等到我真的可以先审核这件事)。我会修补一下,但如果找不到任何可行的话,我会删除它。 – RocketDonkey