Python编写的Azure Function App定时器触发器部署到Azure后无法正常运行
核心问题:业务逻辑未放入main函数作用域
Azure Python定时器触发时,仅会调用执行__init__.py中的main函数,你当前所有PostgreSQL连接、数据查询、Azure SQL写入的代码都写在main函数之外,属于全局初始化代码,仅在函数冷启动时会执行一次,定时器触发时完全不会运行这部分逻辑。本地运行时你看到的执行效果实际是进程启动时全局代码自动运行的结果,并非定时器触发执行的结果。
修复后的__init__.py代码示例
将所有业务逻辑缩进放入main函数内部,同时替换print为logging方便云端排查日志:
import datetime import logging import azure.functions as func # 定时器函数不需要Flask,可以直接删除该依赖减少加载时间 # from flask import Flask # from flask import render_template import psycopg2 import pandas as pd import pyodbc def main(mytimer: func.TimerRequest) -> None: utc_timestamp = datetime.datetime.utcnow().replace( tzinfo=datetime.timezone.utc).isoformat() if mytimer.past_due: logging.info('The timer is past due!') logging.info('Python timer trigger function ran at %s', utc_timestamp) # Start of script 所有业务逻辑移到main函数内部 try: # Connect PostgreSQL pg_host = "###" pg_port = "###" pg_dbname = "###" pg_user = "###" pg_pw = "###" db_conn = psycopg2.connect(host=pg_host, port=pg_port, dbname=pg_dbname, user=pg_user, password=pg_pw) pg_cursor = db_conn.cursor() # Query PostgreSQL pg_sql = 'select "_id", "minute", "hour", "day", "month", "year", "action", "dashlaneRid", "href", "id", "ip", "roleType", "sessionId", "tag", "textContent", "toggle", "url", "userId", "userPib", "utcEpochMillis", "xtag" from click' pg_cursor.execute(pg_sql) query = pg_cursor.fetchall() # Fetch PostgreSQL query in Pandas DataFrame click_df = pd.DataFrame(query, columns=[ '_id','minute','hour','day','month','year','action','dashlaneRid','href','id','ip','roleType','sessionId','tag','textContent','toggle','url','userId','userPib','utcEpochMillis','xtag']) # Azure SQL connect az_server = '###' az_db = '###' az_user = '###' az_pw = '####' cnxn = pyodbc.connect('DRIVER={ODBC Driver 18 for SQL Server};SERVER='+az_server+';DATABASE='+az_db+';UID='+az_user+';PWD='+ az_pw + ';Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;') az_cursor = cnxn.cursor() # Truncate table click az_cursor.execute("TRUNCATE TABLE stage.click;") cnxn.commit() logging.info('Table succesfully truncated') # Fill table click with values for index, row in click_df.iterrows(): az_cursor.execute("INSERT INTO stage.click" "(_id, minute, hour, day, month, year, action, dashlaneRid, href, id, ip, roleType, sessionId, tag, textContent, toggle, url, userId, userPib, utcEpochMillis, xtag) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);" ,row._id, row.minute, row.hour, row.day, row.month, row.year, row.action, row.dashlaneRid, row.href, row.id, row.ip, row.roleType, row.sessionId, row.tag, row.textContent, row.toggle, row.url, row.userId, row.userPib, row.utcEpochMillis, row.xtag) cnxn.commit() az_cursor.close() pg_cursor.close() logging.info('Table successfully filled') except Exception as e: logging.error(f'Execution failed: {str(e)}', exc_info=True) raise e
其他需要排查的配置项
- 依赖声明:确保项目根目录的
requirements.txt文件包含所有依赖,示例如下,用psycopg2-binary替代psycopg2避免Linux环境编译报错:azure-functions psycopg2-binary pandas pyodbc - ODBC驱动安装:如果Function App使用Linux运行时,默认没有SQL Server ODBC驱动,需要在项目根目录新建
startup.sh脚本,添加驱动安装命令,然后在Function App配置页的「启动命令」栏填写./startup.sh。 - 网络权限配置:
- PostgreSQL数据库防火墙规则需放行Function App的所有出站IP,出站IP可在Function App「属性」页面查询
- Azure SQL数据库需开启「允许Azure服务和资源访问此服务器」选项,或单独添加Function App的出站IP到白名单
- 超时配置:如果数据量较大,可修改
host.json中的functionTimeout参数,消耗计划最高支持60分钟超时。 - 日志排查:可在Function App的「日志流」页面实时查看运行日志,定位具体报错。
内容的提问来源于stack exchange,提问作者kremity
相关产品推荐
相关产品推荐

