DEV Community

Goodluck Ekeoma Adiole
Goodluck Ekeoma Adiole

Posted on

Deploying Multiple Python Scripts to Azure Functions as a Cron Job

Ultra-Detailed Step-by-Step Guide: Deploying 4 Python Scripts to Azure Functions as a Cron Job

For absolute beginners — no step skipped!


Before You Start: Prerequisites Checklist

  1. Active Azure Account
  2. VS Code Installed
  3. Install These VS Code Extensions
    • Open VS Code → Extensions (Ctrl+Shift+X) → Search and install:
      • Azure Functions (by Microsoft)
      • Python (by Microsoft)
      • Azure Account (by Microsoft)
  4. Python 3.8+ Installed
    • Download from python.org
    • Verify installation: Open terminal → Type python --version
  5. Node.js (for Azure Tools)
    • Download from nodejs.org
    • Verify: Terminal → node --version

Step 1: Setup Project Folder in VS Code

  1. Create a new folder on your computer (e.g., C:\db-sync-project)
  2. Open VS Code → "File" → "Open Folder" → Select your new folder
  3. Create 4 Python files in VS Code:
    • Right-click in Explorer pane → "New File" → Create:
      • __init__.py (main function)
      • oracle_utils.py
      • mssql_utils.py
      • data_transformer.py
  4. Copy your existing script code into these files

Step 2: Configure Azure Functions Project

  1. Open Integrated Terminal
    • VS Code → Terminal → New Terminal (Ctrl+Shift+`)
  2. Install Azure Functions Tools: bash npm install -g azure-functions-core-tools@4
  3. Create Virtual Environment: bash python -m venv .venv
    • Activate Environment:
      • Windows: .venv\Scripts\activate
      • Mac/Linux: source .venv/bin/activate
  4. Install Required Packages: bash pip install azure-functions cx_Oracle pyodbc python-dotenv
  5. Generate Requirements File: bash pip freeze > requirements.txt

Step 3: Configure Timer Trigger

  1. Create a new folder named SyncFunction in your project
  2. Inside SyncFunction, create function.json with: json { "scriptFile": "../__init__.py", "bindings": [ { "name": "mytimer", "type": "timerTrigger", "direction": "in", "schedule": "*/2 * * * *" // Runs every 2 minutes } ] }
  3. Edit __init__.py (main file): `python import azure.functions as func import logging from .oracle_utils import fetch_data from .data_transformer import transform_data from .mssql_utils import update_database

def main(mytimer: func.TimerRequest):
logging.info("Starting sync...")

   # Step 1: Get data from Oracle
   oracle_data = fetch_data()

   # Step 2: Transform data
   transformed_data = transform_data(oracle_data)

   # Step 3: Update MSSQL
   update_database(transformed_data)

   logging.info("Sync completed successfully!")
Enter fullscreen mode Exit fullscreen mode

`


Step 4: Set Environment Variables

  1. Create local.settings.json in your main project folder: json { "IsEncrypted": false, "Values": { "FUNCTIONS_WORKER_RUNTIME": "python", "AzureWebJobsStorage": "UseDevelopmentStorage=true", "ORACLE_CONN_STR": "your_oracle_connection_string", "MSSQL_CONN_STR": "your_mssql_connection_string" } }
  2. Important! Add this file to .gitignore:
    • Create .gitignore file → Add line: local.settings.json

Step 5: Configure Function Files

File 1: oracle_utils.py

`python
import cx_Oracle
import os
import logging

def fetch_data():
conn_str = os.environ["ORACLE_CONN_STR"]
try:
connection = cx_Oracle.connect(conn_str)
cursor = connection.cursor()
cursor.execute("SELECT * FROM your_table")
return cursor.fetchall()
except Exception as e:
logging.error(f"Oracle error: {str(e)}")
raise
finally:
cursor.close()
connection.close()
`

File 2: mssql_utils.py

`python
import pyodbc
import os
import logging

def update_database(data):
conn_str = os.environ["MSSQL_CONN_STR"]
try:
conn = pyodbc.connect(conn_str)
cursor = conn.cursor()
for row in data:
cursor.execute("UPDATE your_table SET col1=? WHERE id=?", (row[1], row[0]))
conn.commit()
except Exception as e:
logging.error(f"MSSQL error: {str(e)}")
raise
finally:
cursor.close()
conn.close()
`

File 3: data_transformer.py

python
def transform_data(data):
transformed = []
for row in data:
# Add your transformation logic here
transformed.append({
'id': row[0],
'value': row[1].upper() # Example: Convert to uppercase
})
return transformed


Step 6: Test Locally

  1. Start storage emulator (for Windows):
    • Install Azure Storage Emulator
    • Run: AzureStorageEmulator.exe start
  2. In VS Code terminal: bash func start
  3. Verify output: plaintext Functions: SyncFunction: [timerTrigger] Invoked by schedule: */2 * * * *
  4. Wait 2 minutes → Check terminal logs for sync status

Step 7: Deploy to Azure

  1. Sign in to Azure in VS Code:
    • Click Azure icon (left sidebar) → "Sign in to Azure..."
    • Follow browser login prompts
  2. Create Function App:
    • In Azure sidebar → Click "Create Function App" icon (↑+☁️)
    • Follow prompts:
      • Function App Name: db-sync-app-123 (must be globally unique)
      • Runtime: Python 3.10
      • Region: Select closest to you
      • Resource Group: Create new → db-sync-group
  3. Deploy Code:
    • Right-click your project folder in Explorer → "Deploy to Function App"
    • Select your new Function App
    • Wait for deployment (watch Output window)

Step 8: Configure Azure Settings

  1. Go to Azure Portal
  2. Find your Function App → "Configuration" → "Application settings"
  3. Add new settings: | Name | Value | |---|---| | ORACLE_CONN_STR | Your Oracle connection string | | MSSQL_CONN_STR | Your MSSQL connection string | | AzureWebJobsStorage | (Auto-created, don't change) |
  4. Click "Save"

Step 9: Verify Deployment

  1. In Azure Portal → Function App → "Functions"
  2. Select your SyncFunction → "Code + Test"
    • Verify all 4 files appear in file list
  3. Check logs:
    • Go to "Monitor" → "Logs"
    • Run query: kusto traces | order by timestamp desc
  4. Wait 2 minutes → Check for sync logs

Step 10: Troubleshooting Checklist

Deployment failed?

  • Run func azure functionapp publish <APP_NAME> --build remote in terminal
  • Check requirements.txt has all packages

Script not running?

  • Verify timer schedule in function.json: "schedule": "*/2 * * * *"

Database connection issues?

  • Allow Azure IPs in your database firewall:
    • Oracle: Add Azure datacenter IP ranges
    • MSSQL: In Azure SQL → Networking → Add firewall rule for Azure services

Missing files?

  • All files must be in same directory as __init__.py
  • Redeploy entire project folder

Final Validation

  1. Force-run the function:
    • In Azure Portal → Function → "Code + Test" → "Test/Run"
    • Click "Run"
  2. Check "Logs" panel for output
  3. Verify data sync in your MSSQL database

Congratulations! Your 4-script database sync is now running automatically every 2 minutes in Azure! 🎉

Pro Tip: For production, use Azure Key Vault for connection strings:

  1. Create Key Vault in Azure
  2. Store connection strings as secrets
  3. In Function App → Configuration → Add setting: @Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/)

Top comments (0)