示例:使用 Azure 库创建数据库

此示例演示如何使用 Azure SDK for Python 管理库以编程方式创建 Azure Database for MySQL 灵活服务器和相应的数据库。 它还包括一个基本脚本,该脚本使用 mysql-connector-python 库(不是 Azure SDK 的一部分)连接到数据库并查询数据库。

可以通过修改相关的 SDK 导入和 API 调用来调整此示例,以创建 Azure Database for PostgreSQL 灵活服务器。

如果想要使用 Azure CLI,本文稍后会提供 等效的 Azure CLI 命令 。 有关图形体验,请参阅 Azure 门户文档:

除非另有指定,否则所有示例和命令在 Linux/macOS bash 和 Windows 命令行界面中一致工作。

1:设置本地开发环境

如果尚未设置,请设置一个可在其中运行代码的环境。 下面是一些选项:

  • 使用 venv 或所选工具配置 Python 虚拟环境。 若要开始使用虚拟环境,请务必激活它。 若要安装 python,请参阅 “安装 Python”。

    #!/bin/bash
    # Create a virtual environment
    python -m venv .venv
    # Activate the virtual environment
    source .venv/Scripts/activate # only required for Windows (Git Bash)
    
  • 使用 conda 环境。 若要安装 Conda,请参阅 “安装 Miniconda”。

  • Visual Studio CodeGitHub Codespaces中使用 开发容器

2:安装所需的 Azure 库包

在此步骤中,安装创建数据库所需的 Azure SDK 库。

  1. 在控制台中创建一个 requirements.txt 文件,其中列出了此示例中使用的管理库:

    azure-mgmt-resource
    azure-mgmt-rdbms
    azure-identity
    mysql-connector-python
    

    注释

    mysql-connector-python 库不是 Azure SDK 的一部分。 它是第三方库,可用于连接到 MySQL 数据库。 还可以使用其他库(例如 PyMySQLSQLAlchemy)连接到 MySQL 数据库。

  2. 在激活虚拟环境的控制台中,安装要求:

    pip install -r requirements.txt
    

    注释

    在 Windows 上,尝试将 mysql 库安装到 32 位 Python 库中会生成 有关 mysql.h 文件的错误。 在这种情况下,请安装 64 位版本的 Python,然后重试。

3. 设置环境变量

在此步骤中,你将设置环境变量,以便在本文中的代码中使用。 代码使用 os.environ 方法来检索值。

#!/bin/bash
export AZURE_RESOURCE_GROUP_NAME=<ResourceGroupName> # Change to your preferred resource group name
export LOCATION=<Location> # Change to your preferred region
export AZURE_SUBSCRIPTION_ID=$(az account show --query id --output tsv)
export PUBLIC_IP_ADDRESS=$(curl -s https://api.ipify.org)
export DB_SERVER_NAME=<DB_Server_Name> # Change to your preferred DB server name
export DB_ADMIN_NAME=<DB_Admin_Name> # Change to your preferred admin name
export DB_ADMIN_PASSWORD=<DB_Admin_Passwrod> # Change to your preferred admin password
export DB_NAME=<DB_Name> # Change to your preferred database name
export DB_PORT=3306
export version=ServerVersion.EIGHT0_21

4:编写代码以使用数据库创建和配置 MySQL 灵活服务器

在此步骤中,你将使用以下代码创建名为 provision_blob.py 的 Python 文件。 此 Python 脚本使用 Azure SDK for Python 管理库创建资源组、MySQL 灵活服务器和该服务器上的数据库。

import random, os
from azure.identity import DefaultAzureCredential
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.rdbms.mysql_flexibleservers import MySQLManagementClient
from azure.mgmt.rdbms.mysql_flexibleservers.models import Server, ServerVersion

# Acquire a credential object using CLI-based authentication.
credential = DefaultAzureCredential()

# Retrieve subscription ID from environment variable
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

# Retrieve resource group name and ___location from environment variables
RESOURCE_GROUP_NAME = os.environ["AZURE_RESOURCE_GROUP_NAME"]
LOCATION = os.environ["LOCATION"]

# Step 1: Provision the resource group.
resource_client = ResourceManagementClient(credential, subscription_id)

rg_result = resource_client.resource_groups.create_or_update(RESOURCE_GROUP_NAME,
    { "___location": LOCATION })

print(f"Provisioned resource group {rg_result.name}")

# For details on the previous code, see Example: Provision a resource group
# at https://docs.microsoft.com/azure/developer/python/azure-sdk-example-resource-group


# Step 2: Provision the database server

# Retrieve server name, admin name, and admin password from environment variables

db_server_name = os.environ.get("DB_SERVER_NAME")
db_admin_name = os.environ.get("DB_ADMIN_NAME")
db_admin_password = os.environ.get("DB_ADMIN_PASSWORD")

# Obtain the management client object
mysql_client = MySQLManagementClient(credential, subscription_id)

# Provision the server and wait for the result
server_version = os.environ.get("DB_SERVER_VERSION") 

poller = mysql_client.servers.begin_create(RESOURCE_GROUP_NAME,
    db_server_name, 
    Server(
        ___location=LOCATION,
        administrator_login=db_admin_name,
        administrator_login_password=db_admin_password,
        version=ServerVersion[server_version]  # Note: dictionary-style enum access
    )
)

server = poller.result()

print(f"Provisioned MySQL server {server.name}")

# Step 3: Provision a firewall rule to allow the local workstation to connect

RULE_NAME = "allow_ip"
ip_address = os.environ["PUBLIC_IP_ADDRESS"]

# Provision the rule and wait for completion
poller = mysql_client.firewall_rules.begin_create_or_update(RESOURCE_GROUP_NAME,
    db_server_name, RULE_NAME, 
    { "start_ip_address": ip_address, "end_ip_address": ip_address }  
)

firewall_rule = poller.result()

print(f"Provisioned firewall rule {firewall_rule.name}")


# Step 4: Provision a database on the server

db_name = os.environ.get("DB_NAME", "example-db1")
 
poller = mysql_client.databases.begin_create_or_update(RESOURCE_GROUP_NAME,
    db_server_name, db_name, {})

db_result = poller.result()

print(f"Provisioned MySQL database {db_result.name} with ID {db_result.id}")

代码中的身份验证

本文稍后会使用 Azure CLI 登录到 Azure,以执行示例代码。 如果帐户有足够的权限在 Azure 订阅中创建资源组和存储资源,则脚本应成功运行,而无需其他配置。

若要在生产环境中使用,建议通过设置相应的环境变量来向服务主体进行身份验证。 此方法可实现适用于自动化的安全非交互式访问。 有关设置说明,请参阅 如何使用 Azure 服务对 Python 应用进行身份验证

确保为服务主体分配了具有足够权限的角色,例如订阅或资源组级别的参与者角色。 有关分配角色的详细信息,请参阅 Azure 中的基于角色的访问控制(RBAC)。

有关 PostreSQL 数据库服务器,请参阅:

5:运行脚本

  1. 如果尚未登录,请使用 Azure CLI 登录到 Azure:

    az login
    
  2. 运行以下脚本:

    python provision_db.py
    

    脚本需要一两分钟才能完成。

6:插入记录并查询数据库

在此步骤中,将在数据库中创建表并插入记录。 可以使用 mysql-connector 库连接到数据库并运行 SQL 命令。

  1. 使用以下代码创建名为 use_db.py 的文件。

    此代码仅适用于 MySQL;为 PostgreSQL 使用不同的库。

    import os
    import mysql.connector
    
    db_server_name = os.environ["DB_SERVER_NAME"]
    db_admin_name = os.getenv("DB_ADMIN_NAME")
    db_admin_password = os.getenv("DB_ADMIN_PASSWORD")
    
    db_name = os.getenv("DB_NAME")
    db_port = os.getenv("DB_PORT")
    
    connection = mysql.connector.connect(user=db_admin_name,
        password=db_admin_password, host=f"{db_server_name}.mysql.database.azure.com",
        port=db_port, database=db_name, ssl_ca='./BaltimoreCyberTrustRoot.crt.pem')
    
    cursor = connection.cursor()
    
    """
    # Alternate pyodbc connection; include pyodbc in requirements.txt
    import pyodbc
    
    driver = "{MySQL ODBC 5.3 UNICODE Driver}"
    
    connect_string = f"DRIVER={driver};PORT=3306;SERVER={db_server_name}.mysql.database.azure.com;" \
                     f"DATABASE={DB_NAME};UID={db_admin_name};PWD={db_admin_password}"
    
    connection = pyodbc.connect(connect_string)
    """
    
    table_name = "ExampleTable1"
    
    sql_create = f"CREATE TABLE {table_name} (name varchar(255), code int)"
    
    cursor.execute(sql_create)
    print(f"Successfully created table {table_name}")
    
    sql_insert = f"INSERT INTO {table_name} (name, code) VALUES ('Azure', 1)"
    insert_data = "('Azure', 1)"
    
    cursor.execute(sql_insert)
    print("Successfully inserted data into table")
    
    sql_select_values= f"SELECT * FROM {table_name}"
    
    cursor.execute(sql_select_values)
    row = cursor.fetchone()
    
    while row:
        print(str(row[0]) + " " + str(row[1]))
        row = cursor.fetchone()
    
    connection.commit()
    

    所有这些代码都使用 mysql.connector API。 唯一特定于 Azure 的部分是 MySQL 服务器的完整主机域(mysql.database.azure.com)。

  2. 接下来,下载通过 TSL/SSL 与 Azure Database for MySQL 服务器通信所需的证书。 有关详细信息,请参阅 Azure Database for MySQL 文档中 的“获取 SSL 证书 ”。

    #!/bin/bash
    # Download Baltimore CyberTrust Root certificate required for Azure MySQL SSL connections
    CERT_URL="https://www.digicert.com/CACerts/BaltimoreCyberTrustRoot.crt.pem"
    CERT_FILE="BaltimoreCyberTrustRoot.crt.pem"
    echo "Downloading SSL certificate..."
    curl -o "$CERT_FILE" "$CERT_URL"
    
  3. 最后,运行代码:

    python use_db.py
    

如果看到客户端 IP 地址不允许的错误,请检查是否正确定义了环境变量 PUBLIC_IP_ADDRESS 。 如果已使用错误的 IP 地址创建了 MySQL 服务器,则可以在 Azure 门户中添加另一个服务器。 在门户中,选择 MySQL 服务器,然后选择 “连接安全性”。 将工作站的 IP 地址添加到允许的 IP 地址列表中。

7:清理资源

如果不需要保留在此示例中创建的资源组和存储资源,请运行 az group delete 命令。

资源组不会在订阅中产生任何持续费用,但资源组中的资源(如存储帐户)可能会继续产生费用。 清理不经常使用的组是一种很好的做法。 --no-wait 参数允许命令立即返回,而不是等待作完成。

#!/bin/bash
az group delete -n $AZURE_RESOURCE_GROUP_NAME --no-wait

还可以使用 ResourceManagementClient.resource_groups.begin_delete 方法从代码中删除资源组。 示例中的代码 :创建资源组 演示用法。

有关参考:等效的 Azure CLI 命令

以下 Azure CLI 命令完成与 Python 脚本相同的预配步骤。 对于 PostgreSQL 数据库,请使用 az postgres flexible-server 命令。

#!/bin/bash
#!/bin/bash

# Set variables
export LOCATION=<Location> # Change to your preferred region
export AZURE_RESOURCE_GROUP_NAME=<ResourceGroupName> # Change to your preferred resource group name
export DB_SERVER_NAME=<DB_Server_Name> # Change to your preferred DB server name
export DB_ADMIN_NAME=<DB_Admin_Name> # Change to your preferred admin name
export DB_ADMIN_PASSWORD=<DB_Admin_Password> # Change to your preferred admin password
export DB_NAME=<DB_Name> # Change to your preferred database name
export DB_SERVER_VERSION="5.7"

# Get public IP address
export PUBLIC_IP_ADDRESS=$(curl -s https://api.ipify.org)

# Provision the resource group
echo "Creating resource group: $AZURE_RESOURCE_GROUP_NAME"
az group create \
    --___location "$LOCATION" \
    --name "$AZURE_RESOURCE_GROUP_NAME"

# Provision the MySQL Flexible Server
echo "Creating MySQL Flexible Server: $DB_SERVER_NAME"
az mysql flexible-server create \
    --___location "$LOCATION" \
    --resource-group "$AZURE_RESOURCE_GROUP_NAME" \
    --name "$DB_SERVER_NAME" \
    --admin-user "$DB_ADMIN_NAME" \
    --admin-password "$DB_ADMIN_PASSWORD" \
    --sku-name Standard_B1ms \
    --version "$DB_SERVER_VERSION" \
    --yes

# Provision a firewall rule to allow access from the public IP address
echo "Creating firewall rule for public IP: $PUBLIC_IP_ADDRESS"
az mysql flexible-server firewall-rule create \
    --resource-group "$AZURE_RESOURCE_GROUP_NAME" \
    --name "$DB_SERVER_NAME" \
    --rule-name allow_ip \
    --start-ip-address "$PUBLIC_IP_ADDRESS" \
    --end-ip-address "$PUBLIC_IP_ADDRESS"

# Provision the database
echo "Creating database: $DB_NAME"
az mysql flexible-server db create \
    --resource-group "$AZURE_RESOURCE_GROUP_NAME" \
    --server-name "$DB_SERVER_NAME" \
    --database-name "$DB_NAME"

echo "MySQL Flexible Server and database created successfully."

另请参阅