我是 python 编程新手,目前正在学习使用 asyncio 的异步编程。我使用 asyncio 从 sql server 数据库异步读取数据,效果很好。我的问题是,当我学习这样做时,我遇到了一个名为“aioodbc”的 python 库,它指出***“aioodbc 是 Python 3.5+ 模块,可以使用 asyncio 访问 ODBC_ 数据库。”
但是使用 asyncio 库和 pyodbc 可以相当轻松地做到这一点吗?那么为什么要使用 aioodbc 而不是 pyodbc 和 asyncio 呢?我在这里错过了什么吗?
我在下面附上了我用来测试这个的代码,任何对此的反馈将不胜感激
import asyncio
import pyodbc
import pandas as pd
def db_connection():
# await asyncio.sleep(10)
conn = pyodbc.connect(
Trusted_Connection = "Yes",
Driver = '{ODBC Driver 18 for SQL Server}',
Server ="My_db_server",
Database = "test_database",
Encrypt="no"
)
# cursor = conn.cursor()
return conn
async def table_one(conn):
await asyncio.sleep(12)
sql_query_string = "SELECT * FROM test_database.dbo.Employee;"
df = pd.read_sql_query( sql_query_string, conn)
print(df)
async def table_two(conn):
sql_query_string = "SELECT * FROM test_database.dbo.Department;"
df = pd.read_sql_query( sql_query_string, conn)
print(df)
async def dummy():
print("this is the dummy function")
async def main():
conn = db_connection()
task1 = asyncio.create_task(table_one(conn))
task2 = asyncio.create_task(table_two(conn))
task3 = asyncio.create_task(dummy())
print("calling database connection")
await task2
await task1
await task3
asyncio.run(main())
注意:我知道在 pyodbc.connect() 前面添加 await 会导致错误,因为它不是异步函数,但我可以轻松等待主函数中的 db_connection() 函数函数以获得相同的异步功能。
即使在异步函数中调用,对
conn = db_connection()
和 pd.read_sql_query
的调用也将同步执行。因此,在任务 2 完成之前,任务 1 和任务 3 不会执行。为了说明我在说什么:
import asyncio
import time
async def do_task1():
print('start task 1')
time.sleep(1)
print('done task 1')
async def do_task2():
print('start task 2')
time.sleep(1)
print('done task 2')
async def main():
task1 = asyncio.create_task(do_task1())
task2 = asyncio.create_task(do_task2())
await task2
await task1
start_time = time.time()
asyncio.run(main())
total_time = time.time() - start_time
print(total_time)
以下代码执行大约需要 2 秒。切换到使用 asyncio.sleep,代码现在可以在 1 秒内执行:
import asyncio
import time
async def do_task1():
print('start task 1')
await asyncio.sleep(1)
print('done task 1')
async def do_task2():
print('start task 2')
await asyncio.sleep(1)
print('done task 2')
async def main():
task1 = asyncio.create_task(do_task1())
task2 = asyncio.create_task(do_task2())
await task2
await task1
start_time = time.time()
asyncio.run(main())
total_time = time.time() - start_time
print(total_time)
代码可以这样简化:
import asyncio
import time
async def do_task1():
print('start task 1')
await asyncio.sleep(1)
print('done task 1')
async def do_task2():
print('start task 2')
await asyncio.sleep(1)
print('done task 2')
async def main():
task1 = do_task1()
task2 = do_task2()
await asyncio.gather(task1, task2)
start_time = time.time()
asyncio.run(main())
total_time = time.time() - start_time
print(total_time)
使用 aioodbc 将使查询的执行异步,因此允许它们并行执行。您当前的代码将在执行每个查询时阻塞。