如何使用Python异步查询Azure SQL数据库?

Sea*_*ude 3 python asynchronous pyodbc python-asyncio azure-sql-database

我陷入困境,无法找到使用 Python 异步连接到 Azure SQL 数据库的可行方法。

我已经尝试过asynciopyodbcasyncpg没有成功。

这已经很接近了...

import asyncio
import pyodbc

async def query_azure_sql_db():
  connection_string = 'Driver={ODBC Driver 17 for SQL Server};Server=tcp:<mySERVER>.database.windows.net,1433;Database=sqldbstockdata;Uid=<myUN>;Pwd=<myPW>;Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;'

  async with pyodbc.connect(connection_string) as conn:
    async with conn.cursor() as cursor:
      query = 'SELECT * FROM dbo.<myTABLE>'
      await cursor.execute(query)
      results = cursor.fetchall()
      return results

loop = asyncio.get_event_loop()
results = loop.run_until_complete(query_azure_sql_db())
print(results)
Run Code Online (Sandbox Code Playgroud)

但会导致这个神秘的错误:AttributeError: __aenter__

我对其他图书馆持开放态度。

任何帮助表示赞赏。

Art*_*yan 5

问题是这pyodbc.connect是一个函数并且没有实现异步上下文管理器,那么为什么你会得到AttributeError. 我建议使用aioodbc而不是因为pyodbc它提供与方法相同的功能asyncasync with您还可以通过实现__aenter__和dunder 方法来使其工作__aexit__

import asyncio
import aioodbc

class AsyncPyodbc:
    def __init__(self, dsn, autocommit=False, ansi=False, timeout=0,
                 loop=None, executor=None, echo=False, after_created=None, **kwargs):
        self._connection: aioodbc.Connection = aioodbc.connect(dsn=dsn, autocommit=autocommit, ansi=ansi,
                                                               loop=loop, executor=executor, echo=echo,
                                                               timeout=timeout, after_created=after_created, **kwargs)

    async def __aenter__(self) -> aioodbc.Connection:
        return await self._connection

    async def __aexit__(self, *_):
        return await self._connection.close()
Run Code Online (Sandbox Code Playgroud)

这将需要一个事件循环,并将按如下方式使用。

async def query_azure_sql_db():
    connection_string = (
        'Driver={ODBC Driver 17 for SQL Server};'
        'Server=tcp:<mySERVER>.database.windows.net,1433;'
        'Database=sqldbstockdata;Uid=<myUN>;Pwd=<myPW>;'
        'Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;'
    )
    loop = asyncio.get_event_loop()

    async with AsyncPyodbc(connection_string, loop=loop) as conn:
        ...
Run Code Online (Sandbox Code Playgroud)