今川館

都内勤務の地味OLです

MySQLdb SQL文のエスケープ

MySQLdbでcursor.executeをしたときに%sの可変部分をどう処理しているのか調べた。
どうも、connection.literalというメソッドがあるようだ。

    [MySQL-python-1.2.3c1/MySQLdb/cursors.py]
    def execute(self, query, args=None):
    ''' 中略 '''
        if args is not None:
            query = query % db.literal(args)
        try:
            r = self._query(query)

赤字部分のとおり、SQL文の文字列を%している。

# -*- coding: utf-8 -*-

import MySQLdb
from MySQLdb.cursors import DictCursor

def get_connection(connect_info):
    ''' 単純にMySQLのコネクションを作って返します。 '''
    return MySQLdb.connect(**connect_info)

foo = {
    'db' : "imagawa",
    'host' : "",
    'port' : 3306,
    'user' : "user",
    'passwd' : "passwd"
}
connection = get_connection(foo)
cursor = connection.cursor()
print connection.literal(("aaa'bbb'ccc", 77, '99'))
#=> ("'aaa\\'bbb\\'ccc'", '77', "'99'")

なぜこれを調べていたかというと、MySQLdbでuse_resultを使う際は、
cursor#executeが効かなくてconnection#queryしか効かなかったからだ。
connection#queryには文字列しか渡せない。cursor#executeのように、「文字列, タプル」という渡し方ができないのだ。

これだとqueryにはSQL文の可変値を % してから渡さねばならず、
それなら同じ仕組みのcursor#executeはどうしているのだろうと思い、調べた次第。