我在Python中使用以下代码(pyodbc用于MS-Access基础)。
cursor.execute("select a from tbl where b=? and c=?", (x, y))
没关系,但是出于维护目的,我需要知道发送到数据库的完整而准确的SQL字符串 它有可能吗?如何?
答案 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 Storage = 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语句执行任何操作。