Python 함수로 동적 SQL 쿼리 처리

안녕하세요, 저는 새로 온 사람입니다. 개발에 있어서도 비교적 새로운 사람입니다!나는 언젠가 완전한 개발자가 되기를 갈망하며, 모든 영감, 격려, 지도를 기대하고 있다.

문제.


오늘 업무 중에 저는 아주 재미있는 수요를 만났습니다. 처음에는 도전적으로 보였지만 저는 매우 정태적인 SQL 조회 방법에 있어서 눈을 크게 떴습니다.데이터베이스 조회를 요청받을 때마다 다음과 같이 합니다.
SELECT * FROM details WHERE firstName='John' AND lastName='Doe';
내가 말하고 싶은 것은, 나는 정적 조회를 사용할 것이다. 왜냐하면 나는 항상 매개 변수 (열 이름, 열 값, 그리고 다른 자구) 를 알고 있기 때문이다.그러나 오늘날, 나는 사용자가 입력한 모든 테이블에서만 검색할 수 있기를 기대한다. 즉, 이 테이블의 항목이나 검색 검색을 모르는 상황에서 특정한 테이블을 검색할 수 있다.처음에 사용자 입력을 검색 매개 변수로 사용하려는 생각은 나를 곤혹스럽게 했다.나는 동적 SQL 조회를 사용할 가능성을 모른다. (헤헤, 변호해 줘. 나는 아마추어 백엔드 개발자일 뿐이야.) 그러나 이것은 협상할 수 없는 요구이기 때문에 한번 해 보기로 결정했다.

내가 문제를 해결하는 방법


이 특정 프로젝트에 대해 저는 다음과 합작하고 있습니다.
  • Django(Python 웹 프레임워크 - 백엔드)
  • PostgreSQL(RDBMS-데이터베이스)
  • React(JavaScript 라이브러리 - 프런트엔드)
  • 내가 하고 있는 프로젝트는 상당히 복잡하기 때문에 나는 가능한 한 절차를 간단하게 하고 수중의 문제를 해결하는 실제 논리에 더욱 관심을 기울일 것이다.사용자 입력은 가능한 검색 가능한 필드의 이름과 각 필드의 검색 상자로 포착됩니다.그런 다음 사용자가 검색 버튼을 클릭하면 다음과 같이 질의 객체로 백엔드에 전송됩니다.
    const res= await axios.get("http://127.0.0.1:8000/application/search/?query=" + JSON.stringify(queryObj));
    
    검색 대상이 어떤 모양인지 알고 싶으면 입력으로 만들어진 검색 예시가 있습니다 -
    이름: 존
    성: 다이
    let queryObj={firstName:"John", lastName:"Doe",};
    
    백엔드(Django 응용 프로그램\views.py)에서queryObj는 다음과 같이 처리됩니다.
    from django.http import JsonResponse
    import psycopg2
    import ast
    def search_table(request):
      search_query=request.GET.get('query')
      queryparam=ast.literal_eval(search_query)
    
    내가 왜 내장함수ast를 사용했는지 알고 싶지 않기 위해서.여기의literal eval(search query)은 search query가 키 값이 맞는python 사전이 아니라 문자열의 대상이기 때문입니다.이 함수는 search query의 문자열 객체 키를 실제python 사전 키로 변환하는 데 도움을 줍니다.
    다음으로psycopg2를 사용하여postgresql 데이터베이스와 연결합니다.
    from django.http import JsonResponse
    import psycopg2
    import ast
    def search_table(request):
        search_query=request.GET.get('query')
        queryparam=ast.literal_eval(search_query)
        con=psycopg2.connect(database="database_name",user="user_name",password="pwd",host="0.0.0.0",port="12345")
        cursor=con.cursor()
        and_clause=[]
        for k,v in queryparam.items():
            and_clause.append("%s = '%s'" % (k,v))
        and_clause_str=' AND '.join(and_clause)
        sql_query='SELECT * FROM table_name WHERE ' + and_clause_str
        print(sql_query)
        cursor.execute(sql_query)
        result=cursor.fetchall()
        return JsonResponse(result)
    
    따라서 이곳의 코드는 매우 자명하지만, 단지 논리를 빨리 이해하기 위해서-
    나는 SQL 검색처럼 구성할 수 있도록 검색 매개 변수 사전 키를 저장하고 열 이름으로 사용하며, 검색할 매개 변수 사전 값을 검색할 실제 값으로 =로 구분하는 and 자구라는 문자열 목록을 설명했다.
    질의 매개변수 사전에 여러 항목이 있는 경우, 즉 사용자가 여러 매개변수나 열을 기반으로 검색을 원할 때 "AND"를 사용하여 이러한 문자열을 연결하고 AND 자문 str라는 새 문자열 변수에 저장합니다.
    다음은 최종 SQL 문의 모양입니다.

    고려 사항


  • 이 함수는 현재 완전한 동적 조회를 생성하지 않습니다.만약 당신이 주의를 기울였다면, 나는 여전히 표 이름을 지정했고,where 자구도 필요합니다.내가 이렇게 하는 데는 두 가지 이유가 있다.
  • 제가 하고 있는 프로젝트는 데이터베이스에서 검색 작업을 수행하기 위한 것이기 때문에'where'자구는 검색 매개 변수로 존재해야 합니다.
  • 내 프로젝트에서 테이블 이름은 매우 표준적이고 통용되는 테이블 이름이 될 것이다. 이것은 서로 다른 데이터베이스에서 같은 이름으로 유지될 것이다. 그래서 나는 하드코딩 테이블 이름을 가진 조회를 가지고 있다.
  • 나는 SQL 주입에 대한 이해가 여전히 매우 나쁘다. 나는 이 코드가 SQL에 쉽게 주입될 수 있다는 것에 동의한다. 나는 이러한 공격에 의해 공격될 가능성을 방지하기 위해 더욱 최적화할 계획이다.
  • 사용자가 제공한 입력이 테이블의 실제 열 이름이 아니라는 것을 알고 싶다면, 테이블의 단일 열 필드가 백엔드에서 생성된 것이고, 검색을 사용하기 위해 전방으로 보내는 것을 알고 싶습니다.따라서 어느 정도는 기존의 열명만 채운다.
  • 나는 나의 첫 번째 박문이 공정하기를 바란다.나는 이것이 유용하거나, 본문을 읽는 누구에게도 새로운 것으로 증명되기를 정말 바란다.나는 코드를 더욱 강화하는 것에 대한 건의를 듣고, 동적 SQL 조회에 대한 당신의 생각이나 문제를 듣고 싶습니다.
    읽어주셔서 감사합니다!

    좋은 웹페이지 즐겨찾기