如何使用pyodbc和MS-Access在Python cursor.execute中查看真正的SQL查询

时间:2011-03-10 21:59:46

标签: python sql ms-access pyodbc

我在Python中使用以下代码(pyodbc用于MS-Access基础)。

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

没关系,但是出于维护目的,我需要知道发送到数据库的完整而准确的SQL字符串 它有可能吗?如何?

7 个答案:

答案 0 :(得分:39)

它因司机而异。以下是两个例子:

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"

答案 1 :(得分:6)

答案是:不。 我在项目'home Google Code(和Google Group)中发布我的问题答案是:

  

关于问题163的评论#1由l ... @ deller.id.au:cursor.mogrify返回查询字符串   http://code.google.com/p/pyodbc/issues/detail?id=163

     

这里是一个链接   pyscopg他们的文档   “mogrify”游标方法即   记者指的是:   http://initd.org/psycopg/docs/cursor.html#cursor.mogrify

     

pyodbc不执行任何此类操作   SQL的翻译:它通过   直接参数化SQL   ODBC驱动程序逐字。唯一的   涉及的处理是翻译   从Python对象到C的参数   ODBC API支持的类型。

     

SQL的一些转换可能是   在它之前的ODBC驱动程序中执行   被发送到服务器(例如Microsoft   SQL Native Client执行此操作)但这些   变换是隐藏的   pyodbc。

     

因此我认为不是   可行提供mogrify功能   在pyodbc。

答案 2 :(得分:3)

对于调试purpuse我创建了一个简单替换的检查功能?查询值...它不是高科技:)但它的工作原理! :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))

结果:

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

有了这个,您可以记录或做任何你想做的事情:

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

如果您只需要在函数中添加一些异常捕获。

答案 3 :(得分:2)

根据您使用的驱动程序,这可能会也可能不会。在一些数据库中,参数(? s)被简单地替换,因为user589983的答案表明(尽管驱动程序必须做一些事情,比如在字符串中引用字符串和转义引号,以便产生一个语句,即可执行文件)。

其他驱动程序将要求数据库编译(“准备”)该语句,然后让它使用给定的值执行准备好的语句。通过这种方式,使用准备或参数化语句有助于避免SQL注入 - 在语句执行时,数据库“知道”您希望运行的SQL的一部分,以及在内部使用的值的一部分那句话。

通过快速浏览PyODBC documentation来判断,实际执行SQL是不可能的,但我可能错了。

答案 4 :(得分:0)

我使用Wireshark来查看pyodbc中的实际SQL字符串。如果您使用不受保护的服务器连接进行开发,则可能会有所帮助。

答案 5 :(得分:0)

由于pyodbc在执行之前无法查看查询。您可以手动预填充查询,以了解其最终外观。它不能用作实际查询,但可以帮助我弄清楚在查询中是否需要40个以上参数的错误。

def query_dipl_dynamo(key_table,valeur_query,name_table):
    dynamoDBResource = boto3.resource('dynamodb')
    table = dynamoDBResource.Table(name_table)
    response = table.query(
    IndexName:"NameOfTheIndexInDynamoDB",
    KeyConditionExpression=Key(key_table).eq(valeur_query))
    df_fr = pd.DataFrame([response['Items']])
    if len(df_fr.columns) > 0 :
        df = pd.DataFrame([response['Items'][0]])
        return valeur_query, df["dipl_libelle"].iloc[0]
//
//
df9_tmp["dipl_idpp"] = df8_tmp.apply(lambda x : query_dipl_dynamo("dipl_idpp",x["num_auto"], "ddb-dev-PS_LibreAcces_Dipl_AutExerc")[0], axis=1)

答案 6 :(得分:-2)

编写sql字符串然后执行它:

sql='''select a 
       from tbl 
       where b=? 
       and c=? '''

cursor.execute(sql, x, y)
print 'just executed:',(sql, x,y)

现在,您可以使用SQL语句执行任何操作。