복붙노트

[SQL] pyodbc 및 MS-Access를 사용하여 파이썬 cursor.execute에서 실제 SQL 쿼리를 참조하는 방법

SQL

pyodbc 및 MS-Access를 사용하여 파이썬 cursor.execute에서 실제 SQL 쿼리를 참조하는 방법

나는 (A MS-액세스 기지 pyodbc와) 파이썬에서 다음 코드를 사용합니다.

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

그것은 유지 보수 목적을 위해, 나는 데이터베이스에 대한 완전하고 정확한 SQL 문자열 전송을 알고 있어야합니다 확인입니다 만. 그것은 가능한 방법인가?

해결법

  1. ==============================

    1.이 드라이버에 의해 다릅니다. 여기에 두 가지 예는 다음과 같습니다

    이 드라이버에 의해 다릅니다. 여기에 두 가지 예는 다음과 같습니다

    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"
    
  2. ==============================

    2.내 대답은 아니오 야. 나는 (구글 그룹과의) 프로젝트의 홈 Google 코드에 내 질문을 게시하고 대답은 :

    내 대답은 아니오 야. 나는 (구글 그룹과의) 프로젝트의 홈 Google 코드에 내 질문을 게시하고 대답은 :

  3. ==============================

    3.당신은 마지막으로 실행 된 쿼리를 얻을 수 cursor._last_executed 인쇄를 사용할 수 있습니다.

    당신은 마지막으로 실행 된 쿼리를 얻을 수 cursor._last_executed 인쇄를 사용할 수 있습니다.

    당신은 또한 전 또는 실행 한 후 전체 쿼리를보고 인쇄 cursor.mogrify (쿼리 목록)를 사용할 수있는이 답변에 읽어 보시기 바랍니다.

  4. ==============================

    4.디버그 purpuse를 들어 단순히 대체하는 체크 기능을 만들어? 쿼리 값으로 ... 그것은 첨단 기술이 아니다 :)하지만 작품! :디

    디버그 purpuse를 들어 단순히 대체하는 체크 기능을 만들어? 쿼리 값으로 ... 그것은 첨단 기술이 아니다 :)하지만 작품! :디

    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))
    

    결과:

    dbo.MA_ItemsMonthlyBalances SELECT * FROM WHERE 아이템 = 1 및 스토리지 = 2 FiscalYear AND = 'asdasd'AND BalanceYear = 12,331 균형 = 'AAS') = 1 AND BalanceMonth

    이하면 로그인하거나 당신이 원하는 무엇이든 할 수 있습니다 :

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

    당신은 단지 기능을 끄는 몇 가지 예외를 추가해야하는 경우.

  5. ==============================

    5.사용하는 드라이버에 따라이 또는 가능하지 않을 수 있습니다. 일부 데이터베이스에서 매개 변수 (? S) 단순히 user589983의 대답에서 알 수 있듯이, 대체 (드라이버가 실행의 성명이 발생할하기 위해, 문자열을 인용하고 그 문자열 내에서 따옴표를 이스케이프 같은 몇 가지 일을해야합니다하지만).있다

    사용하는 드라이버에 따라이 또는 가능하지 않을 수 있습니다. 일부 데이터베이스에서 매개 변수 (? S) 단순히 user589983의 대답에서 알 수 있듯이, 대체 (드라이버가 실행의 성명이 발생할하기 위해, 문자열을 인용하고 그 문자열 내에서 따옴표를 이스케이프 같은 몇 가지 일을해야합니다하지만).있다

    다른 드라이버는 주어진 값을 사용하여 준비된 문을 실행하도록 요청 후 ( "준비") 컴파일 문을 데이터베이스를 요청하고 있습니다. 그것은 준비 또는 매개 변수가있는 문을 사용하는 것은 피하기 SQL 주입을하는 데 도움이 이러한 방식으로의 - 명령문이 실행되는 시점에, 데이터베이스는 사용자가 실행하고자하는 SQL의 일부 무엇이며 내에서 사용되는 값의 일부로 무엇을 "알고있다" 그 진술.

    PyODBC 문서의 빠른 스키밍에 의해 판단, 실행 된 실제 SQL을 얻는 것이 가능하다는 것을 표시되지 않습니다,하지만 난 잘못 될 수있다.

  6. ==============================

    6.나는 나중에 cursor._last_executed 체크하려고하지만 변화없이 실시간으로 인쇄하려면 모든이 원숭이 패치를 시도 실행 :

    나는 나중에 cursor._last_executed 체크하려고하지만 변화없이 실시간으로 인쇄하려면 모든이 원숭이 패치를 시도 실행 :

    def log_queries(cur):
        def _query(q):
            print q # could also use logging
            return cur._do_query(q)
        cur._query = _query
    
    conn = MySQLdb.connect( read_default_file='~/.my.cnf' )
    cur = conn.cursor()
    log_queries(cur)
    cur.execute('SELECT %s, %s, %s', ('hello','there','world'))
    

    그것은 MySQLdb에 매우 의존적이다 (및 이후 버전에서 깨질 수 있습니다). cur._query 현재 단순히 calls._do_query를 호출하고 그 결과를 반환하기 때문에 작동합니다.

  7. ==============================

    7.나는 pyodbc 실제 SQL 문자열을 볼 수 Wireshark를 사용했다. 당신이 개발을위한 보호되지 않은 서버 연결을 사용하는 경우 그것은 도움이 될 수 있습니다.

    나는 pyodbc 실제 SQL 문자열을 볼 수 Wireshark를 사용했다. 당신이 개발을위한 보호되지 않은 서버 연결을 사용하는 경우 그것은 도움이 될 수 있습니다.

  8. ==============================

    8.pyodbc 때문에이 실행되기 전에 쿼리를 볼 수있는 방법이 없습니다. 당신은처럼 보이는 끝날 어떤 아이디어를 얻을 수동으로 만 쿼리를 미리 채울 수 있습니다. 그것은 실제 쿼리로 작업에 없을거야,하지만 나는 40 개 이상의 매개 변수를 필요로하는 쿼리에 오류가 있다면 저를 알아낼 수있었습니다.

    pyodbc 때문에이 실행되기 전에 쿼리를 볼 수있는 방법이 없습니다. 당신은처럼 보이는 끝날 어떤 아이디어를 얻을 수동으로 만 쿼리를 미리 채울 수 있습니다. 그것은 실제 쿼리로 작업에 없을거야,하지만 나는 40 개 이상의 매개 변수를 필요로하는 쿼리에 오류가 있다면 저를 알아낼 수있었습니다.

    query = """select * from [table_name] where a = ? and b = ?"""
    
    parameter_list = ['dog', 'cat'] # List of parameters, a = 'dog', b = 'cat'.
    
    query_list = list(query) # Split query string into individual characters.
    
    # Loop through list and populate the question marks.
    for i in range(len(parameter_list)):
        for idx, val in enumerate(query_list):
            if val == '?':
                query_list[idx] = str(parameter_list[i])
                break
    
    # Rejoin the query string.
    query_populate = ''.join(query_list)
    
    #### Result ####
    """select * from [table_name] where a = dog and b = cat"""
    
  9. ==============================

    9.를 실행 한 다음 SQL 문자열을 쓰기 :

    를 실행 한 다음 SQL 문자열을 쓰기 :

    sql='''select a 
           from tbl 
           where b=? 
           and c=? '''
    
    cursor.execute(sql, x, y)
    print 'just executed:',(sql, x,y)
    

    이제 당신은 SQL 문을 사용하여 원하는대로 할 수 있습니다.

  10. from https://stackoverflow.com/questions/5266430/how-to-see-the-real-sql-query-in-python-cursor-execute-using-pyodbc-and-ms-acces by cc-by-sa and MIT license