代码之家  ›  专栏  ›  技术社区  ›  Aaron Watters

如何使用python msqldb模块?代替%s查询参数?

  •  3
  • Aaron Watters  · 技术社区  · 17 年前

    mysqldb是一个很棒的python模块——但其中一个部分令人难以置信地恼火。 查询参数如下所示

    cursor.execute("select * from Books where isbn=%s", (isbn,))
    

    而在已知世界的其他地方(Oracle、SQLServer、Access、Sybase…) 它们看起来像这样

    cursor.execute("select * from Books where isbn=?", (isbn,))
    

    这意味着,如果你想便携,你必须以某种方式切换 在两个符号之间?和%s, 真烦人。(请不要告诉我使用 我要勒死你。

    据说你可以说服mysqldb使用标准语法,但我还没有 成功了。有什么建议吗?

    3 回复  |  直到 16 年前
        1
  •  2
  •   Paolo Bergantino    17 年前

    我发现了很多关于 paramstyle 这似乎暗示这可能是你想要的,但是 according to this wiki 你必须使用 小精灵 您的库使用,而且大多数库不允许您更改它:

    小精灵 特定于您使用的库,并且提供信息-您必须使用它使用的库。这可能是这个标准中最烦人的部分。(一些允许您设置不同的 paramstyles ,但这不是标准行为)

    我发现一些帖子提到mysqldb允许这样做,但显然并不像有人说的那样对他们不起作用。

        2
  •  2
  •   Terence Honles    16 年前

    我看你不能用'?'对于参数标记 mysqldb(开箱即用)

    可以 但是使用命名参数

    cursor.execute("%(param1)s = %(param1)s", {'param1':1})
    

    将有效执行 1=1

    在MySQL中

    但是 有点像伊莱回答的(但不是刻薄的)

    你可以这样做:

    mynewcursormodule.py

    import MySQLdb.cursors import Cursor
    
    class MyNewCursor(Cursor):
      def execute(self, query, args=None):
         """This cursor is able to use '?' as a parameter marker"""
         return Cursor.execute(self, query.replace('?', '%s'), args)
    
      def executemany(self, query, args):
         ...implement...
    

    在这种情况下,您将拥有一个自定义光标,它将执行您希望它执行的操作 这不是黑客。只是一个子类;)

    并与以下各项一起使用:

    from MyNewCursorModule import MyNewCursor
    
    conn = MySQLdb.connect(...connection information...
                           cursorclass=MyNewCursor)
    

    (如果大部分时间都想使用普通的execute(临时重写),也可以将类赋给connection.cursor函数在那里创建它)

    …您还可以将简单的替换更改为更正确的替换 (假设有办法逃脱问号),但我会 留给你:)

        3
  •  1
  •   Eli Courtwright    17 年前

    我不建议这么做,但最简单的解决方案是 Cursor 班级:

    from MySQLdb.cursors import Cursor
    old_execute = Cursor.execute
    def new_execute(self, query, args):
       return old_execute(self, query.replace("?", "%s"), args) 
    Cursor.execute = new_execute