빠른 시작: Python용 mssql-python 드라이버를 사용하여 신속한 프로토타입 생성

이 퀵스타트에서는 Streamlit를 사용하여 빠르게 보고서를 작성함으로써 사용자 피드백을 조기에 수집할 수 있습니다. Python용 mssql-python 드라이버를 사용해 데이터베이스에 연결하고 보고서에 로드된 데이터를 읽습니다.

드라이버에는 mssql-python Windows 컴퓨터에 대한 외부 종속성이 필요하지 않습니다. 드라이버는 단일 pip 설치로 필요한 모든 것을 설치하므로 업그레이드 및 테스트할 시간이 없는 다른 스크립트를 중단하지 않고도 새 스크립트에 최신 버전의 드라이버를 사용할 수 있습니다.

mssql-python 설명서 | mssql-python 소스 코드 | 패키지(PyPI) | Uv

필수 조건

운영 체제 설치 전제 조건

일회성 운영 체제 관련 필수 구성 요소를 설치합니다. Windows 사용자는 이 단계를 건너뛸 수 있습니다. 전체 플랫폼 세부사항은 Install mssql-python을 참조하세요.

apk add libtool krb5-libs krb5-dev libstdc++

SQL 데이터베이스 만들기

다음 플랫폼 중 하나에서 SQL 데이터베이스를 생성하거나 연결하세요:

프로젝트 만들기 및 코드 실행

새 프로젝트 만들기

  1. 개발 디렉터리에서 명령 프롬프트를 엽니다. 디렉터리가 없다면, 예를 들어 python 또는 scripts와 같은 새 디렉터리를 만드세요. OneDrive에 폴더를 설치하지 마세요. 동기화가 가상 환경 관리에 방해가 될 수 있습니다.

  2. 를 사용하여 새 프로젝트를 만듭니다 uv.

    uv init rapid-prototyping-qs
    cd rapid-prototyping-qs
    

종속성 추가

동일한 디렉터리에 mssql-python, streamlit, 및 python-dotenv 패키지를 설치합니다.

uv add mssql-python python-dotenv streamlit

Visual Studio Code 시작

동일한 디렉터리에서 다음 명령을 실행합니다.

code .

pyproject.toml 업데이트

  1. 편집기 pyproject.toml 에서 파일을 엽니다. 이 파일은 프로젝트의 메타데이터를 포함하고 있습니다.

  2. description 값을 업데이트하세요.

    description = "A quick example of rapid prototyping using the mssql-python driver and Streamlit."
    
  3. 파일을 저장 후 닫습니다.

main.py를 수정하십시오.

  1. 라는 main.py파일을 엽니다. 이 예제와 유사해야 합니다.

    def main():
        print("Hello from rapid-prototyping-qs!")
    
    if __name__ == "__main__":
        main()
    
  2. 파일 상단에 다음 가져오기 항목을 줄 앞 def main()에 추가하세요.

    팁 (조언)

    Visual Studio Code에서 패키지를 해결하는 데 문제가 있는 경우 가상 환경을 사용하도록 인터프리터를 업데이트해야 합니다.

    from os import getenv
    from dotenv import load_dotenv
    from mssql_python import connect, Connection
    import pandas as pd
    import streamlit as st
    
  3. 가져오기와 줄 def main()사이에 다음 코드를 추가합니다.

    def page_load() -> None:
        st.set_page_config(
            page_title="View Data",
            page_icon=":bar_chart:",
            layout="wide",
            initial_sidebar_state="expanded"
        )
    
        st.title("AdventureWorksLT Customer Order History")
    
        SQL_QUERY = """
        SELECT c.*
        FROM SalesLT.Customer AS c
        INNER JOIN SalesLT.SalesOrderHeader AS soh
            ON c.CustomerID = soh.CustomerID;
        """
    
        df = load_data(SQL_QUERY)
    
        event = st.dataframe(
            df,
            use_container_width=True,
            hide_index=True,
            on_select="rerun",
            selection_mode="single-row"
        )
    
        customer = event.selection.rows
    
        SPEND_QUERY_ALL = """
        SELECT
            soh.OrderDate,
            SUM(sod.OrderQty),
            SUM(sod.OrderQty * sod.UnitPrice) AS spend,
            pc.Name AS ProductCategory
        FROM SalesLT.SalesOrderDetail AS sod
        INNER JOIN SalesLT.SalesOrderHeader AS soh
            ON sod.SalesOrderID = soh.SalesOrderID
        INNER JOIN SalesLT.Product AS p
            ON sod.ProductID = p.ProductID
        INNER JOIN SalesLT.ProductCategory AS pc
            ON p.ProductCategoryID = pc.ProductCategoryID
        GROUP BY soh.OrderDate, pc.Name
        ORDER BY soh.OrderDate, pc.Name;
        """
        SPEND_QUERY_CUSTOMER = """
        SELECT
            soh.OrderDate,
            SUM(sod.OrderQty),
            SUM(sod.OrderQty * sod.UnitPrice) AS spend,
            pc.Name AS ProductCategory
        FROM SalesLT.SalesOrderDetail AS sod
        INNER JOIN SalesLT.SalesOrderHeader AS soh
            ON sod.SalesOrderID = soh.SalesOrderID
        INNER JOIN SalesLT.Product AS p
            ON sod.ProductID = p.ProductID
        INNER JOIN SalesLT.ProductCategory AS pc
            ON p.ProductCategoryID = pc.ProductCategoryID
        WHERE soh.CustomerID = ?
        GROUP BY soh.OrderDate, pc.Name
        ORDER BY soh.OrderDate, pc.Name;
        """
        if len(customer) == 0:
            spend_df = load_data(SPEND_QUERY_ALL)
        else:
            customer_id = int(df.loc[customer, 'CustomerID'].values[0])
            spend_df = load_data(SPEND_QUERY_CUSTOMER, params=(customer_id,))
    
        st.write("Here's a summary of spend by product category over time:")
        st.bar_chart(spend_df.set_index('ProductCategory')['spend'], use_container_width=True)
    
        if len(customer) > 0:
            st.write(f"Displaying orders for Customer ID: {df.loc[customer, 'CustomerID'].values[0]}")
            customer_id = int(df.loc[customer, 'CustomerID'].values[0])
            SQL_QUERY = """
            SELECT *
            FROM SalesLT.SalesOrderHeader AS soh
            WHERE soh.CustomerID = ?;
            """
            st.dataframe(load_data(SQL_QUERY, params=(customer_id,)), hide_index=True, use_container_width=True)
            SQL_QUERY = """
            SELECT sod.*
            FROM SalesLT.SalesOrderHeader AS soh
            INNER JOIN SalesLT.SalesOrderDetail AS sod
                ON soh.SalesOrderID = sod.SalesOrderID
            WHERE soh.CustomerID = ?;
            """
            st.dataframe(load_data(SQL_QUERY, params=(customer_id,)), hide_index=True, use_container_width=True)
    
  4. 가져오기 사이에 def page_load() -> None: 코드를 삽입합니다.

    _connection = None
    
    def get_connection() -> Connection:
        global _connection
        if not _connection:
            load_dotenv()
            _connection = connect(getenv("SQL_CONNECTION_STRING"))
        return _connection
    
    @st.cache_data
    def load_data(SQL_QUERY, params=None) -> pd.DataFrame:
        data = pd.read_sql_query(SQL_QUERY, get_connection(), params=params)
        return data
    
  5. 이 코드를 찾습니다.

    def main():
        print("Hello from rapid-prototyping-qs!")
    
  6. 이 코드로 대체합니다.

    def main() -> None:
        page_load()
        if _connection:
            _connection.close()
    
  7. 저장하고 닫습니다 main.py.

연결 문자열 저장

  1. .gitignore 파일을 열고 .env 파일에 대한 제외를 추가합니다. 귀하의 파일은 다음 예시와 유사해야 합니다.

    # Python-generated files
    __pycache__/
    *.py[oc]
    build/
    dist/
    wheels/
    *.egg-info
    
    # Virtual environments
    .venv
    
    # Connection strings and secrets
    .env
    
  2. 저장하고 닫습니다 .gitignore.

  3. 현재 디렉터리에서 새 파일을 만듭니다 .env.

  4. .env 파일 내부에서 SQL_CONNECTION_STRING이라는 이름의 연결 문자열 항목을 추가합니다. 자리 표시자를 실제 값으로 바꿉다.

    SQL_CONNECTION_STRING="Server=<server>;Database=<database>;Encrypt=yes;TrustServerCertificate=no;Authentication=ActiveDirectoryInteractive"
    

    연결 문자열은 연결하는 SQL 데이터베이스 유형에 따라 다릅니다. Azure SQL Database나 Fabric의 SQL 데이터베이스는 연결 문자열 탭의 ODBC 연결 문자열을 사용하고, 시나리오에 맞는 인증 유형을 조정하세요. 연결 문자열 문법에 대한 자세한 내용은 mssql-python의 Connection strings를 참조하세요.

    팁 (조언)

    macOS에서는 Microsoft Entra 인증을 위해 ActiveDirectoryInteractive 및 ActiveDirectoryDefault가 모두 작동합니다. ActiveDirectoryInteractive 는 스크립트를 실행할 때마다 로그인하라는 메시지를 표시합니다. 반복적인 로그인 프롬프트를 피하려면 Azure CLIaz login 명령어로 한 번 로그인한 후 ActiveDirectoryDefault를 사용하세요. ActiveDirectoryDefault 캐시된 자격 증명을 재사용합니다.

uv run을 사용하여 스크립트 실행

  1. 이전의 터미널 창이나 동일한 디렉터리에 열려 있는 새 터미널 창에서 다음 명령을 실행합니다.

    uv run streamlit run main.py
    

    보고서가 웹 브라우저의 새 탭에서 열립니다.

  2. 보고서의 작동 방식을 확인해 보세요. 변경한 내용이 있으면 브라우저 창의 오른쪽 위 모서리에 있는 다시 로드 옵션을 저장 main.py 하고 사용합니다.

  3. 프로토타입을 공유하려면 폴더를 .venv 제외한 모든 파일을 다른 컴퓨터에 복사합니다. 폴더는 .venv 첫 번째 실행으로 다시 만들어집니다.