views:

118

answers:

3

Hi Everybody,

I have a function with a new improved version of the code for automatic table indexing:

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

While the query 'getIndexMySQLQuery' works fine with this syntax, the other one 'updateIndexMySQLQuery' doesn't work.

Any hints or suggestion how to get that fixed?

All comments and suggestions are highly appreciated.

+2  A: 

Second one doesn't work, because you are using three placeholders inside the query string and provide only one variable for interpolation.

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

This way the string formatting mechanism doesn't expect you to provide 3 values, as the percent signs are "escaped" (shame on me for the first version of the answer).

shylent
A: 

Use %s to replace the table name in the beginning, but use a question mark to create a parameter replacement.

updateIndexMySQLQuery = """UPDATE %s 
SET numberID=? WHERE numberID=?;""" % (tableName,)
...
    self.cursorMySQL.execute(updateIndexMySQLQuery,(updateIndex,indexID))
Tor Valamo
Do question mark placeholders even work with MySQLdb (I know they do in sqlite3)?
shylent
They work with mysql in other languages, so I don't see why not... It's a DBAPI2.0 requirement isn't it?
Tor Valamo
I think, in this case this is a specification of the programming-language-specific db-api, rather than something, that has to do with MySQL itself (I could be wrong). I know, this is a part of python's database api standard, however I know, that MySQLdb's documentation only mentions percent-style placeholders. I can't test it right now so I'll leave it to you :)
shylent
Looked at dbapi, and it says the library decides what to use, but need to specify it in module constant 'format'. So I'm guessing %s style for mysqldb then.
Tor Valamo
Sadly, DBAPI requires *a* parameter type, but it doesn't specify which. You have to look at the module's `paramstyle` to determine which. Some DBAPI modules use the qmark style. MySQLdb uses the `format` style, which unfortunately results in exactly this confusion between parameterisation and string formatting. It's a mess.
bobince
A: 

Hi Guys.. thanks for the input. I just re-did the whole function. Here is how it's working and looks now:

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

So, the only thing to do is to inform the column name and the table name as parameters. It allows to re-use the code for all other tables in the database.

Hope this can be useful for others too.

ThreaderSlash
No, this is not useful at all and, in fact, this is extremely harmful. You should not concatenate the parameter values into the query, but leave it to the database API. How do you ensure, that the parameters you are passing are quoted and escaped properly? In short, do not do it like that.
shylent