【问题标题】:Python - automating MySQL index: passing parameterPython - 自动化 MySQL 索引:传递参数
【发布时间】:2010-01-09 07:24:27
【问题描述】:

我有一个新的改进版本的自动表索引代码的功能:

def update_tableIndex(self,tableName):
    getIndexMySQLQuery = """SELECT numberID
    FROM %s;""" % (tableName,)

    updateIndexMySQLQuery = """UPDATE %s 
    SET numberID=%s WHERE numberID=%s;""" % (tableName,)

    updateIndex=1
    self.cursorMySQL.execute(getIndexMySQLQuery)
    for row in self.cursorMySQL:
        indexID = row[0]
        self.cursorMySQL.execute(updateIndexMySQLQuery,(updateIndex,indexID))
        updateIndex+=1

虽然查询“getIndexMySQLQuery”在此语法下工作正常,但另一个“updateIndexMySQLQuery”不起作用。

任何提示或建议如何解决这个问题?

非常感谢所有 cmets 和建议。

【问题讨论】:

    标签: python mysql parameters automation


    【解决方案1】:

    第二个不起作用,因为您在查询字符串中使用了三个占位符,并且只提供了一个变量用于插值。

    updateIndexMySQLQuery = """UPDATE %s 
    SET numberID=%%s WHERE numberID=%%s;""" % (tableName,)
    

    这样,字符串格式化机制不希望您提供 3 个值,因为百分号被“转义”(对于第一个版本的答案,我感到羞耻)。

    【讨论】:

      【解决方案2】:

      开头使用%s替换表名,但使用问号创建参数替换。

      updateIndexMySQLQuery = """UPDATE %s 
      SET numberID=? WHERE numberID=?;""" % (tableName,)
      ...
          self.cursorMySQL.execute(updateIndexMySQLQuery,(updateIndex,indexID))
      

      【讨论】:

      • 问号占位符是否可以与 MySQLdb 一起使用(我知道它们在 sqlite3 中可以使用)?
      • 它们与其他语言的mysql一起工作,所以我不明白为什么不...这是DBAPI2.0的要求,不是吗?
      • 我认为,在这种情况下,这是特定于编程语言的 db-api 的规范,而不是与 MySQL 本身有关的东西(我可能错了)。我知道,这是 python 的数据库 api 标准的一部分,但是我知道,MySQLdb 的文档只提到了百分比样式的占位符。我现在无法测试它,所以我将它留给你:)
      • 查看了dbapi,它说库决定使用什么,但需要在模块常量'format'中指定它。所以我猜测 mysqldb 的 %s 风格。
      • 遗憾的是,DBAPI 需要 a 参数类型,但它没有指定哪个参数类型。您必须查看模块的paramstyle 以确定哪个。一些 DBAPI 模块使用 qmark 样式。 MySQLdb 使用format 样式,不幸的是,这导致了参数化和字符串格式之间的混淆。真是一团糟。
      【解决方案3】:

      感谢您的意见。我只是重新做了整个功能。以下是它现在的工作方式和外观:

      def update_tableIndex(self,tableName,indexName):
      
          getIndexMySQLQuery = """SELECT %s
          FROM %s;""" % (indexName,tableName,)
      
          updateIndex=1
          self.cursorMySQL.execute(getIndexMySQLQuery)
          for row in self.cursorMySQL:
              indexID = row[0]
      
              updateIndexMySQLQuery = """UPDATE %s 
              SET %s=%s WHERE 
              %s=%s;""" % (tableName,
                           indexName,updateIndex,
                           indexName,indexID)
      
              self.cursorMySQL.execute(updateIndexMySQLQuery)
              updateIndex+=1
      

      所以,唯一要做的就是将列名和表名作为参数通知。它允许重复使用数据库中所有其他表的代码。

      希望这对其他人也有用。

      【讨论】:

      • 不,这根本没有用,事实上,这是极其有害的。您不应将参数值连接到查询中,而应将其留给数据库 API。你如何确保你传递的参数被正确引用和转义?简而言之,不要那样做。
      猜你喜欢
      • 1970-01-01
      • 2018-07-03
      • 2018-06-12
      • 2021-08-15
      • 2013-06-22
      • 1970-01-01
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      相关资源
      最近更新 更多