How to see the real SQL query in Python cursor.execute using pyodbc and MS-Access

前端 未结 9 1388
有刺的猬
有刺的猬 2020-12-04 17:17

I use the following code in Python (with pyodbc for a MS-Access base).

cursor.execute(\"select a from tbl where b=? and c=?\", (x, y))

It\'

相关标签:
9条回答
  • 2020-12-04 18:00

    It differs by driver. Here are two examples:

    import MySQLdb
    mc = MySQLdb.connect()
    r = mc.cursor()
    r.execute('select %s, %s', ("foo", 2))
    r._executed
    "select 'foo', 2"
    
    import psycopg2
    pc = psycopg2.connect()
    r = pc.cursor()
    r.execute('select %s, %s', ('foo', 2))
    r.query
    "select E'foo', 2"
    
    0 讨论(0)
  • 2020-12-04 18:03

    I used Wireshark to see actual SQL string in pyodbc. It may help if you use unprotected server connection for development.

    0 讨论(0)
  • 2020-12-04 18:05

    For debug purpuse I created a check function that simply replaces ? with the query values... it's not high technology :) but it works! :D

    def check_sql_string(sql, values):
        unique = "%PARAMETER%"
        sql = sql.replace("?", unique)
        for v in values: sql = sql.replace(unique, repr(v), 1)
        return sql
    
    query="""SELECT * FROM dbo.MA_ItemsMonthlyBalances
                       WHERE Item = ? AND Storage = ? AND FiscalYear = ? AND BalanceYear = ? AND Balance = ? AND BalanceMonth = ?"""
    values = (1,2,"asdasd",12331, "aas)",1)
    
    print(check_sql_string(query,values))
    

    The result:

    SELECT * FROM dbo.MA_ItemsMonthlyBalances WHERE Item = 1 AND Storage = 2 AND FiscalYear = 'asdasd' AND BalanceYear = 12331 AND Balance = 'aas') AND BalanceMonth = 1

    With this you can log or do whatever you want:

    rowcount = self.cur.execute(query,values).rowcount
    logger.info(check_sql_string(query,values))
    

    If you need just add some exception catching to the function.

    0 讨论(0)
  • 2020-12-04 18:06

    The answer is : NO. I posted my question on the project's home Google Code (and in the Google Group) and the answer is:

    Comment #1 on issue 163 by l...@deller.id.au: cursor.mogrify return query string http://code.google.com/p/pyodbc/issues/detail?id=163

    For reference here is a link to the pyscopg documentation of their "mogrify" cursor method that the reporter is referring to: http://initd.org/psycopg/docs/cursor.html#cursor.mogrify

    pyodbc does not perform any such translations of the SQL: it passes parameterized SQL straight through to the ODBC driver verbatim. The only processing involved is translating parameters from Python objects to C types supported by the ODBC API.

    Some transformation on the SQL may be performed in the ODBC driver before it is sent to the server (eg Microsoft SQL Native Client does this) but these transformations are hidden from pyodbc.

    Consequently I think it is not feasible to provide a mogrify function in pyodbc.

    0 讨论(0)
  • 2020-12-04 18:06

    Depending on the driver you use, this may or may not be possible. In some databases, the parameters (?s) are simply replaced, as user589983's answer suggests (though the driver will have to do some things like quoting strings and escaping quotes within those strings, in order to result in a statement that's executable).

    Other drivers will ask the database to compile ("prepare") the statement, and then ask it to execute the prepared statement using the given values. It's in this way that using prepared or parameterized statements helps avoid SQL injections -- at the time the statement is executing, the database "knows" what is part of the SQL you wish to run, and what is part of a value being used within that statement.

    Judging by a quick skimming of the PyODBC documentation, it doesn't appear that getting the actual SQL executed is possible, but I may be wrong.

    0 讨论(0)
  • 2020-12-04 18:07

    You can use print cursor._last_executed to get the last executed query.

    Read in this answer that you can also use print cursor.mogrify(query,list) to see the full query before or after executing.

    0 讨论(0)
提交回复
热议问题