Python是否支持MySQL准备好的语句?

我之前在一个PHP项目上做了准备,使SELECT查询的速度提高了20%。

我想知道它是否适用于Python? 我似乎无法find任何具体说明它做或不做的事情。

直接回答,不,不。

joshperry的回答是一个很好的解释。

从eugene y回答一个类似的问题 ,

检查MySQLdb 包注释 :

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

所以答案是:不,不。

大多数语言提供了一种通用参数化语句的方法,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, eg '...WHERE name=?' 'numeric' Numeric, positional style, eg '...WHERE name=:1' 'named' Named style, eg '...WHERE name=:name' 'format' ANSI C printf format codes, eg '...WHERE name=%s' 'pyformat' Python extended format codes, eg '...WHERE name=%(name)s' 

在仔细查看MySQLdb包的一个Cursor对象的execute()方法之后(我想这是一种与mysql集成的事实上的包),似乎(至less在缺省情况下)它只执行string内插和引用,而不是实际的参数化查询:

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

如果这不是string插值,那么是什么?

在executemany的情况下,它实际上试图执行插入/replace作为一个单一的陈述,而不是循环执行它。 就是这样,似乎没有魔法。 至less不在其默认行为。

编辑:哦,我刚刚意识到,模运算符可以被覆盖,但我觉得就像作弊和grepped来源。 虽然没有在任何地方find一个被重写的mod

如果您只关心性能,使用Amitbuild议的SQL接口可以工作。 但是,然后,您将失去SQL注入的防护能力,即对准备语句的本地Python支持可能带来的影响。 Python 3具有为PostgreSQL提供预备语句支持的模块。 对于MySQL,“oursql”似乎提供了真正的准备好的语句支持(不像其他模块那样伪造)。

对于试图解决这个问题的人来说, 是的,您可以使用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

不直接相关,但是对于SO中的另一个问题的这个答案包括“模板化”查询的语法细节。 我会说,自动逃脱将是他们最重要的function…

至于性能,请注意游标对象的executemany方法。 它捆绑了许多查询,并一次执行所有查询,从而提高了性能。

有一个解决scheme!

你可以使用它们,如果你把它们放在服务器上的存储过程,并从Python中调用它们像这样…

 cursor.callproc(Procedurename, args) 

这里是一个很好的教程在MySQL和Python的存储过程。

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