Python SQLite如何获取正在执行的SQL字符串语句

时间:2012-11-30 13:55:13

标签: python sql sqlite

假设我们有一个SQL语句,只需要在对DB执行之前用参数完成。例如:

sql = '''
      SELECT  id, price, date_out
      FROM sold_items
      WHERE date_out BETWEEN ? AND ?
      '''

database_cursor.execute(sql, (start_date, end_date))

如何获取解析和执行的字符串?,如下所示:

SELECT  id, price, date_out
FROM sold_items
WHERE date_out BETWEEN 2010-12-05 AND 2011-12-01

在这个简单的情况下它并不是很重要,但是我的其他SQL语句要复杂得多,出于调试目的,我想在我的sqlite管理器中自己执行它们并检查结果。

提前致谢

4 个答案:

答案 0 :(得分:12)

更新。我从this web page了解到,自Python 3.3起,您可以使用

触发已执行SQL的打印
connection.set_trace_callback(print)

如果您想恢复静默处理,请使用

connection.set_trace_callback(None)

您可以使用其他功能代替print

答案 1 :(得分:8)

SQLite实际上从未将参数替换为SQL查询字符串本身;参数的值在执行命令时直接读取。 (格式化这些值只是为了将它们再次解析为相同的值将是无用的开销。)

但是如果你想知道如何在SQL中编写参数,你可以使用quote function;像这样的东西:

import re
def log_and_execute(cursor, sql, *args):
    s = sql
    if len(args) > 0:
        # generates SELECT quote(?), quote(?), ...
        cursor.execute("SELECT " + ", ".join(["quote(?)" for i in args]), args)
        quoted_values = cursor.fetchone()
        for quoted_value in quoted_values:
            s = s.replace('?', quoted_value, 1)
            #s = re.sub(r'(values \(|, | = )\?', r'\g<1>' + quoted_value, s, 1)
    print "SQL command: " + s
    cursor.execute(sql, args)

(如果?不是参数,那么此代码将失败,即在文字字符串中。除非你使用re.sub版本,它只匹配一个'after'值(' ','或'='。'\ g&lt; 1&gt;'在?之前放回文本,并使用'\ g&lt;&gt;'避免与以数字开头的quoted_values发生冲突。)

答案 2 :(得分:0)

我编写了一个函数,该函数只用参数填充问号。

每个人都向您发送使用位置参数的指导,这很奇怪,但是没有人想到需要记录,预览或检查全部查询。

无论如何,下面的代码假定

  • 没有'?'查询中的标记不能用作位置参数标记。我不确定情况是否总是如此。
  • 该参数的值将用引号引起来。例如,当您为表名使用参数时,情况并非如此。不过,这种用例不太可能。
    def compile_query(query, *args):
        # test for mismatch in number of '?' tokens and given arguments
        number_of_question_marks = query.count('?')
        number_of_arguments = len(args)

        # When no args are given, an empty tuple is passed
        if len(args) == 1 and (not args[0]):
            number_of_arguments = 0
        
        if number_of_arguments != number_of_question_marks:
            return f"Incorrect number of bindings supplied. The current statement uses {number_of_question_marks}, and there are {number_of_arguments} supplied."

        # compile query
        for a in args:
            query = query.replace('?', "'"+str(a)+"'", 1)

        return query

建议用法

query = "INSERT INTO users (name, password) VALUES (?, ?)"

# sensitive query, we need to log this for security
query_string = compile_query(query, username, password_hash)
fancy_log_function(query_string)

# execute
cursor.execute(query, username, password_hash)

答案 3 :(得分:-2)

字符串格式化怎么样?

sql = """
  SELECT  id, price, date_out
  FROM sold_items
  WHERE date_out BETWEEN {0} AND {1} """.format(start_date, end_date)
  """
database_cursor.execute(sql)