Azure:错误:('01000',“[01000] [unixODBC][驱动程序管理器]无法打开 lib 'ODBC Driver 18 for SQL Server':找不到文件 (0) (SQLDriverConnect)”)

问题描述 投票:0回答:1

我写了这个Python脚本:

import time
import json
import pyodbc
import textwrap
import datetime
import logging
import azure.functions as func
import os 

def default(o):
    """Converts our Dates and Datetime Objects to Strings."""
    if isinstance(o, (datetime.date, datetime.datetime)):
        return o.isoformat()


def main(req: func.HttpRequest) -> func.HttpResponse:

    logging.info('Python HTTP Database trigger function processed a request.')

    database_username = 'Lophios'
    database_password = '*******'

    # Load the Database Credentials.
    logging.info('Loaded Database Credentials.')

    # Grab the table name.
    table_name = 'filing_AAPL'  # Change this to your desired table name

    # Grba the Drivers.
    logging.info(pyodbc.drivers())

    # Create the full connection string
    connection_string = (
        f'DRIVER=ODBC Driver 18 for SQL Server;'
        f'SERVER=lophios-server.database.windows.net,1433;'
        f'DATABASE=sec-filling;'
        f'UID={database_username};'
        f'PWD={database_password};'
        f'Encrypt=yes;'
        f'TrustServerCertificate=no;'
        f'Connection Timeout=30;'
    )

    # Create a new connection.
    try:
        cnxn: pyodbc.Connection = pyodbc.connect(connection_string)
    except pyodbc.OperationalError:
        time.sleep(2)
        cnxn: pyodbc.Connection = pyodbc.connect(connection_string)

    logging.info(msg='Database Connection Successful.')

    # Create the Cursor Object.
    cursor_object: pyodbc.Cursor = cnxn.cursor()

    # Define the Query.
    upsert_query = textwrap.dedent("""
    SELECT TOP 100 * FROM [dbo].[{table_name}]
    """.format(table_name=table_name))

    # Execute the Query.
    cursor_object.execute(upsert_query)

    # Grab the Records.
    records = list(cursor_object.fetchall())

    # Clean them up so we can dump them to JSON.
    records = [tuple(record) for record in records]

    logging.info(msg='Query Successful.')

    if records:

        # Return the Response.
        return func.HttpResponse(
            body=json.dumps(obj=records, indent=4, default=default),
            status_code=200
        )

我已经能够在本地运行它,但是当我将它部署到 azure 上的函数应用程序并尝试测试/运行时,我收到此错误:“HTTP 响应代码 500 内部服务器错误”。当我转到 Monitor 查看调用详细信息时,我得到:

Result: Failure Exception: Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib 'ODBC Driver 18 for SQL Server' : file not found (0) (SQLDriverConnect)") Stack: File "/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/dispatcher.py", line 479, in _handle__invocation_request call_result = await self._loop.run_in_executor( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run result = self.fn(*self.args, **self.kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/dispatcher.py", line 752, in _run_sync_func return ExtensionManager.get_sync_invocation_wrapper(context, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/azure-functions-host/workers/python/3.11/LINUX/X64/azure_functions_worker/extension.py", line 215, in _raw_invocation_wrapper result = function(**args) ^^^^^^^^^^^^^^^^ File "/home/site/wwwroot/sec_http_trigger/__init__.py", line 46, in main cnxn: pyodbc.Connection = pyodbc.connect(connection_string) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

此外,当我寻找网络/连接故障排除程序时,我得到了这个结果:

Network connectivity tests to common Function App dependencies failed.
Network connectivity test to Azure storage endpoint configured in app setting "AzureWebJobsStorage" failed.
Connection attempt to the Blob Storage account resource configured for connection "AzureWebJobsStorage" failed. (This is preview feature)
Network connectivity test to the Azure storage endpoint configured in app setting "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING" failed. This can result in the Function App not starting up.
Connection attempt to the File Share Storage account resource configured for connection "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING" failed.

这是我的 local.settings.json 文件:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=sechttptriggerd7043c;AccountKey=98HrxSUQ8e7jjCTb/Fga5LwF3Bk+Lxy67UV6p7ix+g8EjnRsHh/h2hxjidcRM08TA3zvnv/G911j+AStrVMlIw==;EndpointSuffix=core.windows.net",
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "connectionstring" : "DRIVER={ODBC Driver 18 for SQL Server};SERVER=tcp:lophios-server.database.windows.net;PORT=1433;DATABASE=sec-filling;UID=Lophios;PWD=******"
  }
}

我的requirements.txt文件

azure-functions
pyodbc

这是我的 AzureWebJobStorage 配置:

DefaultEndpointsProtocol=https;AccountName=sechttptriggerd7043c;AccountKey=98HrxSUQ8e7jjCTb/Fga5LwF3Bk+Lxy67UV6p7ix+g8EjnRsHh/h2hxjidcRM08TA3zvnv/G911j+AStrVMlIw==;EndpointSuffix=core.windows.net

和我的 WEBSITE_CONTENTAZUREFILECONNECTIONSTRING :

DefaultEndpointsProtocol=https;AccountName=sechttptriggerd7043c;AccountKey=98HrxSUQ8e7jjCTb/Fga5LwF3Bk+Lxy67UV6p7ix+g8EjnRsHh/h2hxjidcRM08TA3zvnv/G911j+AStrVMlIw==;EndpointSuffix=core.windows.net

我还在 CORS 面板中选中了启用 Access-Control-Allow-Credentials 并将我的 url 函数应用程序添加到“允许的来源”。

我使用的是 MacOs ARM64 处理器,我认为此信息不相关,因为我正在尝试使其在我的 azure 门户上运行,但我将其放在这里是因为我在使用 brew 和安装 PYODBC 时遇到了一些问题但我使用了 Rosetta,现在一切都可以在本地运行。

python azure function pyodbc
1个回答
0
投票

我在我的环境中重现也遇到了类似的错误。 如下图:

enter image description here

要解决此问题,您需要在代码中使用 17 版本而不是 18。

 f'DRIVER=ODBC Driver 17 for SQL Server;'

正如你在下面看到的,它对我有用。

这是我获取SYSTEM_USER的简单代码:

import azure.functions as func
import pyodbc
import logging
import os

 
def sql_result(query):
      
    try:
        Connectionstring = os.environ["connectionstring"]
        with pyodbc.connect(Connectionstring) as conn:
            with conn.cursor() as cursor:
                cursor.execute(query)
                result = cursor.fetchone()  # Fetch the result
                return result[0] if result else None
                
    except pyodbc.Error as e:
        logging.error(f"SQL query failed: {e}")    
        

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')
    
    
    system_user = sql_result("SELECT SYSTEM_USER;")
    logging.info("SYSTEM_USER: %s", system_user)

 

    return func.HttpResponse(f"SYSTEM_USER: {system_user}", status_code=200)

我正在从本地环境中的我的local.settings.json导入连接字符串值。

在Azure中,我已经添加了它的值。
我的功能->环境变量->应用程序设置。

enter image description here

如果您从应用程序设置中导入连接字符串的值,则其值应与 [" < name >"]

中的值相同
os.environ["connectionstring"]

输出: enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.