Compartir vía


Ejemplo: Uso de las bibliotecas de Azure para crear una base de datos

En este ejemplo se muestra cómo usar las bibliotecas de administración del SDK de Azure en un script de Python para crear una base de datos y una instancia de servidor flexible de Azure Database for MySQL. También proporciona un script sencillo para consultar la base de datos mediante la biblioteca mysql-connector, que no forma parte de Azure SDK. Puede usar código similar para crear una instancia de servidor flexible y una base de datos Azure Database for PostgreSQL.

Más adelante en este artículo se indican los comandos equivalentes de la CLI de Azure. Si prefiere usar Azure Portal, consulte Creación de un servidor MySQL o Creación de un servidor PostgreSQL.

Todos los comandos de este artículo funcionan igual en el bash de Linux o macOS y en los shells de comandos de Windows, a menos que se indique lo contrario.

1: Configuración del entorno de desarrollo local

Si aún no lo ha hecho, configure un entorno en el que pueda ejecutar el código. Estas son algunas opciones:

2: Instalación de los paquetes de biblioteca de Azure necesarios

Cree un archivo llamado requirements.txt con el siguiente contenido:

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

En un terminal con el entorno virtual activado, instale los requisitos:

pip install -r requirements.txt

Nota:

En Windows, si intenta instalar la biblioteca de MySQL en una biblioteca de Python de 32 bits, se produce un error con el archivo mysql.h. En este caso, instale una versión de 64 bits de Python e inténtelo de nuevo.

3: Escritura de código para crear la base de datos

Cree un archivo de Python llamado provision_db.py con el siguiente código. Los detalles se explican en los comentarios. En concreto, especifique variables de entorno para AZURE_SUBSCRIPTION_ID y PUBLIC_IP_ADDRESS. Esta última variable es la dirección IP de la estación de trabajo para que se ejecute este ejemplo. Puede usar WhatsIsMyIP para buscar la dirección IP.

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"]

# Constants we need in multiple places: the resource group name and the region
# in which we provision resources. You can change these values however you want.
RESOURCE_GROUP_NAME = 'PythonAzureExample-DB-rg'
LOCATION = "southcentralus"

# 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

# We use a random number to create a reasonably unique database server name.
# If you've already provisioned a database and need to re-run the script, set
# the DB_SERVER_NAME environment variable to that name instead.
#
# Also set DB_USER_NAME and DB_USER_PASSWORD variables to avoid using the defaults.

db_server_name = os.environ.get("DB_SERVER_NAME", f"python-azure-example-mysql-{random.randint(1,100000):05}")
db_admin_name = os.environ.get("DB_ADMIN_NAME", "azureuser")
db_admin_password = os.environ.get("DB_ADMIN_PASSWORD", "ChangePa$$w0rd24")

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

# Provision the server and wait for the result
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.FIVE7
    )
)

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"]

# For the above code, create an environment variable named PUBLIC_IP_ADDRESS that
# contains your workstation's public IP address as reported by a site like
# https://whatismyipaddress.com/.

# 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}")

Autenticación en el código

Más adelante en este artículo, debe iniciar sesión en Azure con la CLI de Azure para ejecutar el código de ejemplo. Si la cuenta tiene permisos para crear grupos de recursos y recursos de almacenamiento en la suscripción de Azure, el código se ejecutará correctamente.

Para usar este código en un script de producción, puede establecer variables de entorno para usar un método basado en la entidad de servicio para la autenticación. Para más información, consulte Autenticación de aplicaciones de Python con los servicios de Azure. Debe asegurarse de que la entidad de servicio tenga permisos suficientes para crear grupos de recursos y recursos de almacenamiento en la suscripción mediante la asignación de un rol adecuado en Azure; por ejemplo, el rol Colaborador de la suscripción.

Para el servidor de bases de datos PostreSQL, consulte:

4: Ejecución del script

  1. Si aún no lo ha hecho, inicie sesión en Azure mediante la CLI de Azure:

    az login
    
  2. Establezca las variables de entorno AZURE_SUBSCRIPTION_ID y PUBLIC_IP_ADDRESS. Puede ejecutar el comando az account show para obtener el identificador de suscripción de la propiedad id en la salida. Puede usar WhatsIsMyIP para buscar la dirección IP.

    set AZURE_SUBSCRIPTION_ID=00000000-0000-0000-0000-000000000000
    set PUBLIC_IP_ADDRESS=<Your public IP address>
    
  3. Opcionalmente, establezca las variables de entorno DB_SERVER_NAME, DB_ADMIN_NAME y DB_ADMIN_PASSWORD; de lo contrario, se usan los valores predeterminados de código.

  4. Ejecute el script:

    python provision_db.py
    

5: Inserción de un registro y consulta de la base de datos

Cree un archivo llamado use_db.py con el código siguiente. Tenga en cuenta las dependencias de las variables de entorno DB_SERVER_NAME, DB_ADMIN_NAME y DB_ADMIN_PASSWORD. Estos valores se obtienen de la salida de la ejecución del código anterior provision_db.py o en el propio código.

Este código solo funciona para MySQL; use bibliotecas diferentes para PostgreSQL.

import os
import mysql.connector

db_server_name = os.environ["DB_SERVER_NAME"]
db_admin_name = os.getenv("DB_ADMIN_NAME", "azureuser")
db_admin_password = os.getenv("DB_ADMIN_PASSWORD", "ChangePa$$w0rd24")

db_name = os.getenv("DB_NAME", "example-db1")
db_port = os.getenv("DB_PORT", 3306)

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()

Todo este código usa la API mysql.connector. El único elemento específico de Azure es el dominio host completo del servidor MySQL (mysql.database.azure.com).

A continuación, descargue el certificado necesario para comunicarse mediante TSL/SSL con el servidor de Azure Database for MySQL de https://www.digicert.com/CACerts/BaltimoreCyberTrustRoot.crt.pem y guarde el archivo de certificado en la misma carpeta que el archivo de Python. Para más información, consulte Obtención de un certificado SSL en la documentación de Azure Database for MySQL.

Finalmente, ejecute el código:

python use_db.py

Si ve un error que indica que la dirección IP del cliente no está permitida, compruebe que ha definido correctamente la variable de entorno PUBLIC_IP_ADDRESS. Si ya ha creado el servidor MySQL con la dirección IP incorrecta, puede agregar otro en Azure Portal. En el portal, seleccione el servidor MySQL y, a continuación, seleccione Seguridad de conexión. Agregue la dirección IP de la estación de trabajo a la lista de direcciones IP permitidas.

6: Limpieza de recursos

Ejecute el comando az group delete si no necesita conservar el grupo de recursos y los recursos de almacenamiento creados en este ejemplo.

Los grupos de recursos no incurren en cargos continuos en la suscripción, pero los recursos, como las cuentas de almacenamiento en el grupo de recursos pueden seguir incurriendo en cargos. Es recomendable limpiar cualquier grupo que no esté usando activamente. El argumento --no-wait permite que el comando devuelva el control inmediatamente en lugar de esperar a que finalice la operación.

az group delete -n PythonAzureExample-DB-rg  --no-wait

También puede usar el método ResourceManagementClient.resource_groups.begin_delete para eliminar un grupo de recursos del código. El código de Ejemplo: Creación de un grupo de recursos muestra el uso.

Como referencia: comandos equivalentes de la CLI de Azure

Los siguientes comandos de la CLI de Azure realizan los mismos pasos de aprovisionamiento que el script de Python. Para una base de datos postgreSQL, use comandos az postgres flexible-server.

az group create --location southcentralus --name PythonAzureExample-DB-rg

az mysql flexible-server create --location southcentralus --resource-group PythonAzureExample-DB-rg ^
    --name python-azure-example-mysql-12345 --admin-user azureuser --admin-password ChangePa$$w0rd24 ^
    --sku-name Standard_B1ms --version 5.7 --yes

# Change the IP address to the public IP address of your workstation, that is, the address shown
# by a site like https://whatismyipaddress.com/.

az mysql flexible-server firewall-rule create --resource-group PythonAzureExample-DB-rg --name python-azure-example-mysql-12345 ^
    --rule-name allow_ip --start-ip-address 10.11.12.13 --end-ip-address 10.11.12.13

az mysql flexible-server db create --resource-group PythonAzureExample-DB-rg --server-name python-azure-example-mysql-12345 ^
    --database-name example-db1

Consulte también