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/