Python支持MySQL预处理语句吗?

时间:2009-12-22 17:06:47

标签: python mysql prepared-statement

我之前参与过一个PHP项目,其中预处理语句使SELECT查询的速度提高了20%。

我想知道它是否适用于Python?我似乎无法找到任何明确说明它做或不做的事。

7 个答案:

答案 0 :(得分:59)

大多数语言提供了一种做泛型参数化语句的方法,Python也不例外。使用参数化查询时,支持准备语句的数据库将自动执行此操作。

在python中,参数化查询如下所示:

cursor.execute("SELECT FROM tablename WHERE fieldname = %s", [value])

参数化的具体方式可能因驱动程序而异,您可以导入数据库模块,然后执行print yourmodule.paramstyle

来自PEP-249

  

paramstyle

       String constant stating the type of parameter marker
       formatting expected by the interface. Possible values are
       [2]:

           'qmark'         Question mark style, 
                           e.g. '...WHERE name=?'
           'numeric'       Numeric, positional style, 
                           e.g. '...WHERE name=:1'
           'named'         Named style, 
                           e.g. '...WHERE name=:name'
           'format'        ANSI C printf format codes, 
                           e.g. '...WHERE name=%s'
           'pyformat'      Python extended format codes, 
                           e.g. '...WHERE name=%(name)s'

答案 1 :(得分:13)

直接回答,不是。

joshperry's answer很好地解释了它的作用。

来自eugene y answer to a similar question

  

检查MySQLdb Package Comments

     
    

“参数化”是在MySQLdb中通过转义字符串然后盲目地将它们插入到查询中而不是使用     MYSQL_STMT API。因此,unicode字符串必须通过两个     中间表示(编码字符串,转义编码字符串)     在他们被数据库收到之前。

  
     

所以答案是:不,它没有。

答案 2 :(得分:10)

快速浏览一下MySQLdb包的Cursor对象的execute()方法(我认为是一种与mysql集成的事实包),似乎(至少在默认情况下)它只是进行字符串插值和引用,而不是实际的参数化查询:

if args is not None:
    query = query % db.literal(args)

如果这不是字符串插值,那么是什么?

在executemany的情况下,它实际上尝试将insert / replace作为单个语句执行,而不是在循环中执行它。这就是它,似乎没有魔法。至少不是默认行为。

编辑:哦,我刚刚意识到,模数运算符可以被覆盖,但我觉得像是作弊并且使用了gp来源。但是,在任何地方都没有找到覆盖mod

答案 3 :(得分:5)

如果您只关心性能,则使用Amit建议的SQL接口可以正常工作。但是,您将失去对SQL注入的保护,而本机Python对预准备语句的支持可能会带来这种保护。 Python 3具有为PostgreSQL提供预处理语句支持的模块。对于MySQL,“oursql”似乎提供了真实的语句支持(不像其他模块那样伪造)。

答案 4 :(得分:5)

对于那些想要解决这个问题的人来说,你可以使用Python和MySQL的预处理语句。只需使用MySQL本身的MySQL Connector / Python并实例化正确的光标:

https://dev.mysql.com/doc/connector-python/en/index.html

https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursorprepared.html

答案 5 :(得分:1)

没有直接相关,但是this answer在SO处的另一个问题包括“模板化”查询的语法详细信息。我会说自动逃逸将是他们最重要的特征......

至于性能,请注意光标对象上的方法executemany。它捆绑了许多查询并一次性执行它们, 可以带来更好的性能。

答案 6 :(得分:0)

有一个解决方案!

如果将它们放入服务器上的存储过程并从python中调用它们,就可以使用它们。

cursor.callproc(Procedurename, args)

这是关于mysql和python中存储过程的一个很好的小教程。

http://www.mysqltutorial.org/calling-mysql-stored-procedures-python/