【问题标题】:azure function using pyodbc works fine on local machine, but not on azure cloud使用 pyodbc 的 azure 函数在本地机器上运行良好,但在 azure 云上却不行
【发布时间】:2021-10-31 23:53:34
【问题描述】:

我开发了一个简单的 python Azure 函数应用程序,使用 pyodbc 从公共 IP MS SQL 服务器中选择几行。我的函数应用程序在我的笔记本电脑上运行良好,但是当我在 Azure 云上发布它时它不起作用(我使用消费 - 无服务器计划,linux 环境)。通过日志记录,我知道它总是卡在 pyodbc.connect(...) 命令和超时。

#...
conn_str = f'Driver={driver};Server={server},{port};Database={database};Uid={user};Pwd={password};Encrypted=yes;TrustServerCertificate=no;Connection Timeout=30'
sql_query = f'SELECT * FROM {table_name}'
try:
    conn = pyodbc.connect(conn_str) # always time-out here if running on Azure cloud!!!
    logging.info(f'Inventory API - connected to {server}, {port}, {user}.')
except Exception as error:
    logging.info(f'Inventory API - connection error: {repr(error)}.')
else:
    with conn.cursor() as cursor:
        cursor.execute(sql_query)
        logging.info(f'Inventory API - executed query: {sql_query}.')
        data = []
        for row in cursor:
            data.append({'Sku' : row.Sku, 'InventoryId' : row.InventoryId, 'LocationId' : row.LocationId, 'AvailableQuantity' : row.AvailableQuantity})
#...

捕获的日志记录:

Inventory API - connection error: OperationalError('HYT00', '[HYT00] [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired (0) (SQLDriverConnect)').

我已经在 requirements.txt 文件中包含了 pyodbc。我还在我的 SQL 服务器防火墙上允许我的函数应用程序的所有 outboundIpAddresses 和可能的OutboundIpAddresses。我的函数应用在 Azure 云上没有任何网络限制(或者至少在网络设置上是这样说的)。

我的配置文件:

driver={ODBC Driver 17 for SQL Server}
server=I tried both IP and full internet host name, both didn't work

有人可以给我一个提示吗?谢谢。

【问题讨论】:

    标签: python azure-functions


    【解决方案1】:

    解决PYODBC 连接错误的解决方法

    尝试使用以下格式

    import pyodbc
    server = 'tcp:myserver.database.windows.net'
    database = 'mydb'
    username = 'myusername'
    password = 'mypassword'
    conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
    

    如果您使用 Domain 名称添加 TCP 与域名 server = 'tcp:myserver.database.windows.net' 否则使用 IP @ 987654325@

    如果您使用 port,请像这样使用 'tcp:myserver.database.windows.net,1233’'129.0.0.1,1233'

    尝试删除 Connection_TimeoutTrusted_certificate 等其他属性并立即检查。

    参考here

    【讨论】:

    • 我试过但没用。超时错误仍然发生。
    • 您是否尝试删除 connection_timeout !?
    • 是的,我做到了,但是没有用。我找到了根本原因并修复了它。
    【解决方案2】:

    我将下面的sn-p放入我的函数中检查出站IP,发现Azure使用了[outboundIpAddresses]和[possibleOutboundIpAddresses]中未列出的几个出站IP(documented in this MS link

    import requests
    #...
    outbound_ip_response = requests.request('GET', 'https://checkip.amazonaws.com')
    logging.info(f'Inventory API - main()- outbound ip = {outbound_ip_response.text}')
    

    因此,我按照link 中的说明为我的函数应用设置了一个静态出站 IP,并允许该 IP 访问我的 SQL 服务器。它奏效了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-22
      • 1970-01-01
      • 2019-02-11
      • 1970-01-01
      • 2011-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多