Share via


Python 및 pyodbc 드라이버를 사용하여 Azure SQL Database에 대한 커넥트 및 쿼리

적용 대상:Azure SQL Database

이 빠른 시작에서는 애플리케이션을 Azure SQL Database의 데이터베이스에 연결하고 Python 및 Python SQL Driver - pyodbc를 사용하여 쿼리를 수행하는 방법을 설명합니다. 이 빠른 시작은 데이터베이스에 연결하는 데 권장되는 암호 없는 방법을 따릅니다. 암호 없는 허브에서 암호 없는 연결에 대해 자세히 알아볼 수 있습니다.

필수 구성 요소

  • Azure 구독.
  • Microsoft Entra 인증으로 구성된 Azure SQL 데이터베이스입니다. 데이터베이스 만들기 빠른 시작을 사용하여 만들 수 있습니다.
  • Azure CLI최신 버전입니다.
  • Python 확장이 있는 Visual Studio Code입니다.
  • Python 3.8 이상. Linux 클라이언트 컴퓨터를 사용하는 경우 ODBC 드라이버 설치를 참조하세요.

데이터베이스 구성

Azure SQL Database에 대한 암호 없는 보안 연결에는 특정 데이터베이스 구성이 필요합니다. 로컬 및 호스트된 환경 모두에서 Azure SQL Database에 제대로 연결하려면 Azure 의 논리 서버에서 다음 설정을 확인합니다.

  1. 로컬 개발 연결의 경우 논리 서버가 로컬 컴퓨터 IP 주소 및 기타 Azure 서비스에 연결할 수 있도록 구성되어 있는지 확인합니다.

    • 서버의 네트워킹 페이지로 이동합니다.

    • 선택한 네트워크 라디오 단추를 전환하여 추가 구성 옵션을 표시합니다.

    • 클라이언트 IPv4 주소 추가(xx.xx.xx.xx.xx)를 선택하여 로컬 컴퓨터 IPv4 주소에서 연결을 사용하도록 설정하는 방화벽 규칙을 추가합니다. 또는 + 방화벽 규칙 추가를 선택하여 원하는 특정 IP 주소를 입력할 수도 있습니다.

    • Azure 서비스 및 리소스가 이 서버에 액세스할 수 있도록 허용 검사 상자가 선택되어 있는지 확인합니다.

      방화벽 규칙을 구성하는 방법을 보여 주는 스크린샷

      Warning

      Azure 서비스 및 리소스가 이 서버 설정에 액세스하도록 허용하는 것은 프로덕션 시나리오에 권장되는 보안 관행이 아닙니다. 실제 애플리케이션은 더 강력한 방화벽 제한 또는 가상 네트워크 구성과 같은 보다 안전한 접근 방식을 구현해야 합니다.

      다음 리소스에서 데이터베이스 보안 구성에 대해 자세히 읽을 수 있습니다.

  2. 또한 서버에는 Microsoft Entra 인증이 사용하도록 설정되어 있어야 하며 Microsoft Entra 관리자 계정이 할당되어 있어야 합니다. 로컬 개발 연결의 경우 Microsoft Entra 관리자 계정은 로컬로 Visual Studio 또는 Azure CLI에 로그인할 수도 있는 계정이어야 합니다. 논리 서버의 Microsoft Entra ID 페이지에서 서버에 Microsoft Entra 인증이 활성화되어 있는지 확인할 수 있습니다.

    Microsoft Entra 인증을 사용하도록 설정하는 방법을 보여 주는 스크린샷

  3. 개인 Azure 계정을 사용하는 경우 계정을 서버 관리자로 할당하기 위해 Azure SQL Database에 대해 Microsoft Entra를 설정 및 구성했는지 확인합니다. 회사 계정을 사용하는 경우 Microsoft Entra ID가 이미 구성되어 있을 가능성이 큽니다.

프로젝트 만들기

Visual Studio Code를 사용하여 새 Python 프로젝트를 만듭니다.

  1. Visual Studio Code를 열고 프로젝트에 대한 새 폴더를 만들고 디렉터리를 변경합니다.

    mkdir python-sql-azure
    cd python-sql-azure
    
  2. 앱에 대한 가상 환경을 만듭니다.

    py -m venv .venv
    .venv\scripts\activate
    
  3. 라는 새 Python 파일을 만듭니다 app.py.

pyodbc 드라이버 설치

Python을 사용하여 Azure SQL Database에 연결하려면 드라이버를 설치합니다 pyodbc . 이 패키지는 데이터베이스에 연결하고, 명령을 실행하고, 결과를 검색하기 위한 데이터 공급자 역할을 합니다. 이 빠른 시작에서는 API를 만들고 실행하는 패키지도 설치 flaskuvicornpydantic 합니다.

모든 운영 체제에 드라이버를 설치하기 pyodbc 위한 자세한 내용 및 구체적인 지침은 pyodbc Python 개발을 위한 개발 환경 구성을 참조하세요.

  1. 다음 줄을 사용하여 requirements.txt 파일을 만듭니다.

    pyodbc
    fastapi
    uvicorn[standard]
    pydantic
    azure-identity
    
  2. 요구 사항을 설치합니다.

    pip install -r requirements.txt
    

로컬 연결 문자열 구성

로컬 개발 및 Azure SQL Database에 연결하려면 다음 AZURE_SQL_CONNECTIONSTRING 환경 변수를 추가합니다. <database-server-name><database-name> 자리 표시자를 고유한 값으로 바꿉니다. Bash 셸에 대한 환경 변수 예제가 표시됩니다.

대화형 인증은 로컬로 실행할 때 암호 없는 옵션을 제공합니다.

Windows에서 Microsoft Entra Interactive Authentication은 Microsoft Entra 다단계 인증 기술을 사용하여 연결을 설정할 수 있습니다. 이 모드에서는 로그인 ID를 제공하여 Azure 인증 대화 상자가 트리거되고 사용자가 암호를 입력하여 연결을 완료할 수 있습니다.

export AZURE_SQL_CONNECTIONSTRING='Driver={ODBC Driver 18 for SQL Server};Server=tcp:<database-server-name>.database.windows.net,1433;Database=<database-name>;Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30'

자세한 내용은 ODBC 드라이버와 함께 Microsoft Entra ID 사용을 참조 하세요. 이 옵션을 사용하는 경우 자격 증명을 묻는 창을 찾습니다.

세부 정보를 가져와서 Azure Portal에서 연결 문자열 만들 수 있습니다.

  1. Azure SQL Server로 이동하여 SQL 데이터베이스 페이지를 선택하여 데이터베이스 이름을 찾은 다음 데이터베이스를 선택합니다.

  2. 데이터베이스에서 커넥트ion 문자열 페이지로 이동하여 연결 문자열 정보를 가져옵니다. ODBC 탭을 찾습니다.

참고 항목

Azure Arc설치하고 Azure 구독과 연결한 경우 App Service에 배포된 앱에 대해 표시된 관리 ID 접근 방식을 사용할 수도 있습니다.

Azure SQL Database에 연결하는 코드 추가

프로젝트 폴더에서 app.py 파일을 만들고 샘플 코드를 추가합니다. 이 코드는 다음과 같은 API를 만듭니다.

  • 환경 변수에서 Azure SQL Database 연결 문자열 검색합니다.
  • Persons 시작하는 동안 데이터베이스에 테이블을 만듭니다(테스트 시나리오에만 해당).
  • 데이터베이스에서 모든 Person 레코드를 검색하는 함수를 정의합니다.
  • 데이터베이스에서 하나의 Person 레코드를 검색하는 함수를 정의합니다.
  • 데이터베이스에 새 Person 레코드를 추가하는 함수를 정의합니다.
import os
import pyodbc, struct
from azure import identity

from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel

class Person(BaseModel):
    first_name: str
    last_name: Union[str, None] = None
    
connection_string = os.environ["AZURE_SQL_CONNECTIONSTRING"]

app = FastAPI()

@app.get("/")
def root():
    print("Root of Person API")
    try:
        conn = get_conn()
        cursor = conn.cursor()

        # Table should be created ahead of time in production app.
        cursor.execute("""
            CREATE TABLE Persons (
                ID int NOT NULL PRIMARY KEY IDENTITY,
                FirstName varchar(255),
                LastName varchar(255)
            );
        """)

        conn.commit()
    except Exception as e:
        # Table may already exist
        print(e)
    return "Person API"

@app.get("/all")
def get_persons():
    rows = []
    with get_conn() as conn:
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM Persons")

        for row in cursor.fetchall():
            print(row.FirstName, row.LastName)
            rows.append(f"{row.ID}, {row.FirstName}, {row.LastName}")
    return rows

@app.get("/person/{person_id}")
def get_person(person_id: int):
    with get_conn() as conn:
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM Persons WHERE ID = ?", person_id)

        row = cursor.fetchone()
        return f"{row.ID}, {row.FirstName}, {row.LastName}"

@app.post("/person")
def create_person(item: Person):
    with get_conn() as conn:
        cursor = conn.cursor()
        cursor.execute(f"INSERT INTO Persons (FirstName, LastName) VALUES (?, ?)", item.first_name, item.last_name)
        conn.commit()

    return item

def get_conn():
    credential = identity.DefaultAzureCredential(exclude_interactive_browser_credential=False)
    token_bytes = credential.get_token("https://database.windows.net/.default").token.encode("UTF-16-LE")
    token_struct = struct.pack(f'<I{len(token_bytes)}s', len(token_bytes), token_bytes)
    SQL_COPT_SS_ACCESS_TOKEN = 1256  # This connection option is defined by microsoft in msodbcsql.h
    conn = pyodbc.connect(connection_string, attrs_before={SQL_COPT_SS_ACCESS_TOKEN: token_struct})
    return conn

Warning

샘플 코드는 프로덕션 코드에서 사용하면 안 되는 원시 SQL 문을 보여 줍니다. 대신 데이터베이스에 액세스하기 위해 보다 안전한 개체 계층을 생성하는 SqlAlchemy와 같은 ORM(개체 관계형 매퍼) 패키지를 사용합니다.

로컬에서 앱 실행 및 테스트

앱을 로컬로 테스트할 준비가 된 것입니다.

  1. app.py Visual Studio Code에서 파일을 실행합니다.

    uvicorn app:app --reload
    
  2. http://127.0.0.1:8000/docs의 Swagger UI 페이지에서 POST 메서드 를 확장하고 사용해 보세요.

    try /redoc 를 사용하여 API에 대해 생성된 다른 형태의 설명서를 볼 수도 있습니다.

  3. 이름과 성의 값을 포함하도록 샘플 JSON을 수정합니다. 실행을 선택하여 데이터베이스에 새 레코드를 추가합니다. API는 성공적인 응답을 반환합니다.

  4. Swagger UI 페이지에서 GET 메서드를 확장하고 [시도]를 선택합니다. 실행을 선택하면 방금 만든 사람이 반환됩니다.

Azure App Service에 배포

Azure에 앱을 배포할 준비가 완료되었습니다.

  1. Azure 앱 Service의 gunicorn이 uvicorn을 실행할 수 있도록 start.sh 파일을 만듭니다. start.sh 한 줄이 있습니다.

    gunicorn -w 4 -k uvicorn.workers.UvicornWorker app:app
    
  2. az webapp up을 사용하여 App Service에 코드를 배포합니다. (이 옵션을 -dryrun 사용하여 리소스를 만들지 않고 명령이 수행하는 작업을 확인할 수 있습니다.)

    az webapp up \
        --resource-group <resource-group-name> \
        --name <web-app-name>         
    
  3. az webapp config set 명령을 사용하여 start.sh 파일을 사용하도록 App Service를 구성합니다.

    az webapp config set \
        --resource-group <resource-group-name> \
        --name <web-app-name> \
        --startup-file start.sh
    
  4. az webapp identity assign 명령을 사용하여 App Service에 대해 시스템 할당 관리 ID를 사용하도록 설정합니다.

    az webapp identity assign \
        --resource-group <resource-group-name> \
        --name <web-app-name>
    

    이 빠른 시작에서는 시스템 할당 관리 ID를 데모에 사용합니다. 사용자 할당 관리 ID는 광범위한 시나리오에서 더 효율적입니다. 자세한 내용은 관리 ID 모범 사례 권장 사항을 참조 하세요. pyodbc에서 사용자 할당 관리 ID를 사용하는 예제는 Azure SQL Database와 암호 없는 연결을 사용하도록 Python 애플리케이션 마이그레이션을 참조하세요.

Azure SQL Database에 App Service 커넥트

데이터베이스 구성 섹션에서 Azure SQL 데이터베이스 서버에 대한 네트워킹 및 Microsoft Entra 인증을 구성했습니다. 이 섹션에서는 데이터베이스 구성을 완료하고 연결 문자열 사용하여 App Service를 구성하여 데이터베이스 서버에 액세스합니다.

이러한 명령을 실행하려면 SQL Server mssql 확장을 사용하여 SSMS(SQL Server Management Studio), Azure Data Studio 및 Visual Studio Code를 포함하여 Azure SQL Database에 연결할 수 있는 모든 도구 또는 IDE를 사용할 수 있습니다. 또한 빠른 시작에서 설명 한 대로 Azure Portal을 사용할 수 있습니다. Azure Portal 쿼리 편집기를 사용하여 Azure SQL Database를 쿼리합니다.

  1. SQL 명령을 사용하여 Azure SQL Database에 사용자를 추가하여 암호 없는 액세스에 대한 사용자 및 역할을 만듭니다.

    CREATE USER [<web-app-name>] FROM EXTERNAL PROVIDER
    ALTER ROLE db_datareader ADD MEMBER [<web-app-name>]
    ALTER ROLE db_datawriter ADD MEMBER [<web-app-name>]
    

    자세한 내용은 포함된 데이터베이스 사용자 - 데이터베이스를 이식 가능하게 만들기를 참조하세요. 동일한 원칙을 보여 주지만 Azure VM에 적용되는 예제는 자습서: Windows VM 시스템 할당 관리 ID를 사용하여 Azure SQL에 액세스하는 방법을 참조하세요. 할당된 역할에 대한 자세한 내용은 고정 데이터베이스 역할을 참조 하세요.

    App Service 시스템 할당 관리 ID를 사용하지 않도록 설정한 다음 사용자를 삭제하고 다시 만듭니다. 및 명령을 실행하고 DROP USER [<web-app-name>] 다시 실행 CREATE 합니다.ALTER 사용자를 보려면 .를 사용합니다 SELECT * FROM sys.database_principals.

  2. az webapp config appsettings set 명령을 사용하여 연결 문자열 대한 앱 설정을 추가합니다.

    az webapp config appsettings set \
        --resource-group <resource-group-name> \
        --name <web-app-name> \
        --settings AZURE_SQL_CONNECTIONSTRING="<connection-string>"
    

    배포된 앱의 경우 연결 문자열 다음과 유사해야 합니다.

    Driver={ODBC Driver 18 for SQL Server};Server=tcp:<database-server-name>.database.windows.net,1433;Database=<database-name>;Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30
    

    <dabaser-server-name> 값을 입력합니다<database-name>.

    암호 없는 연결 문자열 사용자 이름 또는 암호를 포함하지 않습니다. 대신 앱이 Azure에서 실행되면 코드는 Azure ID 라이브러리에서 사용하여 DefaultAzureCredential 사용할 pyodbc토큰을 가져옵니다.

배포된 애플리케이션 테스트

앱의 URL로 이동하여 Azure SQL Database에 대한 연결이 작동하는지 테스트합니다. App Service 개요 페이지에서 앱의 URL을 찾을 수 있습니다.

https://<web-app-name>.azurewebsites.net

URL에 /docs를 추가하여 Swagger UI를 확인하고 API 메서드를 테스트합니다.

축하합니다! 이제 애플리케이션이 로컬 및 호스트된 환경 모두에서 Azure SQL Database에 연결됩니다.