次の方法で共有


Python と mssql-python ドライバーを使用して Azure SQL Database に接続してクエリを実行する

適用対象:Azure SQL Database

このクイック スタートでは、Azure SQL Database のデータベースにアプリケーションを接続し、Python と mssql-python ドライバーを使用してクエリを実行する方法について説明します。 mssql-python ドライバーには、Microsoft Entra 認証のサポートが組み込まれており、パスワードレス接続が簡単になります。 パスワードレス接続について詳しくは、パスワードレス ハブに関する記事を参照してください。

前提条件

データベースを構成する

Azure SQL Database への安全なパスワードレス接続には、特定のデータベース構成が必要です。 Azure の論理サーバーで次の設定を確認し、ローカル環境とホスト環境の両方で Azure SQL Database に適切に接続します。

  1. ローカル開発の接続の場合は、ローカル コンピューターの IP アドレスやその他の Azure サービスで接続できるように論理サーバーが構成されていることを確認します。

    • お使いのサーバーの [ネットワーク] ページに移動します。

    • [選択されたネットワーク] ラジオ ボタンを切り替えて、追加の構成オプションを表示します。

    • [Add your client IPv4 address(xx.xx.xx.xx)] (クライアント IPv4 アドレスの追加 (xx.xx.xx.xx)) を選び、ローカル コンピューターの IPv4 アドレスからの接続を有効にするファイアウォール規則を追加します。 または、[+ Add a firewall rule] (ファイアウォール規則の追加) を選び、選んだ特定の IP アドレスを入力することもできます。

    • [Azure サービスおよびリソースにこのサーバーへのアクセスを許可する] チェックボックスがオンになっていることを確認します。

      ファイアウォール規則を構成する方法を示すスクリーンショット。

      警告

      [Azure サービスおよびリソースにこのサーバーへのアクセスを許可する] 設定を有効にすることは、運用環境のシナリオでは推奨されるセキュリティ プラクティスではありません。 実際のアプリケーションでは、より強力なファイアウォール制限や仮想ネットワーク構成など、より安全なアプローチを実装する必要があります。

      データベース セキュリティの構成について詳しくは、次のリソースを参照してください。

  2. また、サーバーでは Microsoft Entra 認証が有効になっており、Microsoft Entra 管理者アカウントが割り当てられている必要があります。 ローカル開発接続の場合、Microsoft Entra 管理者アカウントは、ローカルで Visual Studio または Azure CLI にログインできるアカウントである必要があります。 論理サーバーの Microsoft Entra ID ページで、サーバーで Microsoft Entra 認証が有効になっているかどうかを確認できます。

    Microsoft Entra 認証を有効にする方法を示すスクリーンショット。

  3. 個人の Azure アカウントを使用している場合は、アカウントをサーバー管理者として割り当てるために、Microsoft Entra がセットアップされ、Azure SQL Database 用に構成されていることを確認してください。企業アカウントを使用している場合は、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. app.py という名前の新しい Python ファイルを作成します。

mssql-python ドライバーをインストールする

Python を使って Azure SQL Database に接続するには、mssql-python ドライバーをインストールします。 このドライバーには、Microsoft Entra 認証のサポートが組み込まれているため、手動でのトークン処理は不要です。 このクイックスタートでは、API を作成して実行するために、fastapiuvicornpydantic パッケージもインストールします。

macOS と Linux では、 mssql-pythonをインストールする前にシステムの依存関係が必要です。 プラットフォーム固有の手順については、 mssql-python パッケージのインストール を参照してください。

  1. 次の行を含む requirements.txt ファイルを作成します。

    mssql-python
    fastapi
    uvicorn[standard]
    pydantic
    python-dotenv
    
  2. 要件をインストールします。

    pip install -r requirements.txt
    

ローカル接続文字列を構成する

ローカル開発の場合は、プロジェクト フォルダーに .env ファイルを作成して接続文字列を格納します。 これにより、資格情報がコードとソース管理から除外されます。

  1. プロジェクト フォルダーに、 .envという名前の新しいファイルを作成します。

  2. 接続文字列を使用して AZURE_SQL_CONNECTIONSTRING 変数を追加します。 プレースホルダー <database-server-name><database-name> を実際の値に置き換えます。

mssql-python ドライバーには、Microsoft Entra 認証のサポートが組み込まれています。 認証方法を指定するには、 Authentication パラメーターを使用します。

ActiveDirectoryDefault は、対話型ログインを必要とせずに、複数のソースから資格情報を自動的に検出します。 これは、 ローカル開発に推奨されるオプションです

最も信頼性の高いローカル開発エクスペリエンスを実現するには、まず Azure CLI でサインインします。

az login

次に、 .env ファイルで次の接続文字列形式を使用します。

AZURE_SQL_CONNECTIONSTRING=Server=<database-server-name>.database.windows.net;Database=<database-name>;Authentication=ActiveDirectoryDefault;Encrypt=yes;TrustServerCertificate=no;

ActiveDirectoryDefault は、次の順序で資格情報を評価します。

  1. 環境変数 (サービス プリンシパル資格情報の場合)
  2. マネージド ID (Azure で実行されている場合)
  3. Azure CLI ( az loginから)
  4. Visual Studio (Windows のみ)
  5. Azure PowerShell ( Connect-AzAccount から)

ヒント

運用アプリケーションの場合は、資格情報の検出の待機時間を回避するために、シナリオに固有の認証方法を使用します。

  • Azure App Service/Functions: ActiveDirectoryMSI (マネージド ID) を使用する
  • 対話型ユーザー ログイン: 使用 ActiveDirectoryInteractive
  • サービス プリンシパル: 使用 ActiveDirectoryServicePrincipal

接続文字列を作成するための詳細は、Azure portal から入手できます。

  1. Azure SQL Server に移動し、[SQL データベース] ページを選んでデータベース名を検索して、データベースを選びます。

  2. データベースで、[ 概要 ] ページに移動してサーバー名を取得します。

Azure SQL Database に接続するコードを追加する

プロジェクト フォルダーに app.py ファイルを作成して、サンプル コードを追加します。 このコードでは、次のことを行う API が作成されます。

  • .envを使用して、python-dotenv ファイルから構成を読み込みます。
  • 環境変数から Azure SQL Database の接続文字列を取得します。
  • 起動時にデータベース内に Persons テーブルを作成します (テスト シナリオ専用)。
  • データベースからすべての Person レコードを取得する関数を定義します。
  • データベースからす 1 つの Person レコードを取得する関数を定義します。
  • データベースに新しい Person レコードを追加する関数を定義します。
from os import getenv
from typing import Union
from dotenv import load_dotenv
from fastapi import FastAPI
from pydantic import BaseModel
from mssql_python import connect

load_dotenv()

class Person(BaseModel):
    first_name: str
    last_name: Union[str, None] = None

connection_string = getenv("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("""
            IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Persons')
            CREATE TABLE Persons (
                ID int NOT NULL PRIMARY KEY IDENTITY,
                FirstName varchar(255),
                LastName varchar(255)
            );
        """)

        conn.commit()
        conn.close()
    except Exception as e:
        # Table might 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("INSERT INTO Persons (FirstName, LastName) VALUES (?, ?)",
                       (item.first_name, item.last_name))
        conn.commit()

    return item

def get_conn():
    """Connect using mssql-python with built-in Microsoft Entra authentication."""
    conn = connect(connection_string)
    conn.setautocommit(True)
    return conn

警告

サンプル コードでは生の SQL ステートメントが示されており、運用環境のコードではこれを使わないでください。 代わりに、データベースにアクセスするためのより安全なオブジェクト レイヤーを生成する、SqlAlchemy のようなオブジェクト リレーショナル マッパー (ORM) パッケージを使ってください。

アプリをローカルで実行してテストする

アプリをローカルでテストする準備ができました。

  1. Visual Studio Code で app.py ファイルを実行します。

    uvicorn app:app --reload
    
  2. アプリ用の Swagger UI ページ http://127.0.0.1:8000/docs で、POST メソッドを展開し、[Try it out] (試してみる) を選びます。

    /redocを試して、API用に生成された別形式のドキュメントを確認することもできます。

  3. 姓と名の値を含むようにサンプル JSON を変更します。 [実行] を選択して、新しいレコードをデータベースに追加します。 API は正常な応答を返します。

  4. Swagger UI ページで GET メソッドを展開し、[ 試してみる] を選択します。 [実行] を選択すると、先ほど作成した人物が返されます。

Azure App Service にデプロイする

アプリを Azure にデプロイする準備ができました。

  1. Azure App Service の gunicorn で uvicorn を実行できるように、start.sh ファイルを作成します。 start.sh の内容は次の 1 行です。

    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 のベスト プラクティスに関する推奨事項」をご覧ください。 mssql-python でユーザー割り当てマネージド ID を使用する例については、「 Azure SQL Database でのパスワードレス接続を使用するための Python アプリケーションの移行」を参照してください。

App Service を Azure SQL Database に接続する

データベースを構成する」セクションでは、Azure SQL Database サーバー用のネットワークと Microsoft Entra 認証を構成しました。 このセクションでは、データベースの構成を完了し、データベース サーバーにアクセスするための接続文字列を使って App Service を構成します。

これらのコマンドを実行するには、SQL Server Management Studio (SSMS)MSSQL 拡張機能を使用した Visual Studio Code など、Azure SQL Database に接続できる任意のツールまたは IDE を使用できます。 「 クイック スタート: Azure portal クエリ エディターを使用して Azure SQL Database にクエリを実行する」の説明に従って、Azure portal を使用することもできます。

  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>] コマンドを実行し、CREATEALTER コマンドを実行し直します。 ユーザーを表示するには、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>"
    

    デプロイされたアプリの接続文字列は次のようになります。

    Server=<database-server-name>.database.windows.net;Database=<database-name>;Authentication=ActiveDirectoryMSI;Encrypt=yes;TrustServerCertificate=no;
    

    <database-server-name><database-name> では、実際の値を指定します。

    パスワードレスの接続文字列には、ユーザー名またはパスワードは含まれません。 代わりに、アプリが Azure で実行されている場合、mssql-python ドライバーは、 ActiveDirectoryMSI 認証モードを使用して、App Service のマネージド ID を使用して自動的に認証します。

デプロイされたアプリケーションをテストする

アプリの URL を参照して、Azure SQL Database への接続が動作していることをテストします。 アプリの URL は、App Service の概要ページで確認できます。

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

を URL に追加して Swagger UI を表示し、API メソッドをテストします。

おめでとうございます。 これで、ローカル環境とホスト環境の両方で、アプリケーションを Azure SQL Database に接続することができました。