报错信息:
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
报错说明:这个错误提示表明你正在从异步环境中调用一个同步操作
你是不是使用django + playwright实现web ui自动化测试平台的时候出现过这样的问题?
接下来我来教你怎么解决这个问题(个人观点,仅供参考):
with sync_playwright() as playwright:
browser = playwright.firefox.launch(headless=False)
context = browser.new_context(viewport={'width': width, 'height': height})
context.tracing.start(screenshots=True, snapshots=True, sources=True)
driver = context.new_page()
web_resolve_script(driver, context)
以上是我启动playwright的写法,本身是异步启动。
def run():
res_dict = {}
# 利用多线程,调用sync_change_async(),紧接着处理我们想要的数据库操作
t = threading.Thread(target=sync_change_async, args=(res_dict,))
t.start()
t.join()
def sync_change_async(data):
# 创建一个新的事件循环,然后异步将其设置为当前事件循环
# 启动 create_result_coroutine() 协程。
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(aysnc_wait_coroutine(data))
async def aysnc_wait_coroutine(data):
# 协程内部等待异步执行
await create_result_async(data)
@sync_to_async
def create_result_async(result):
# 函数使用 @sync_to_async 装饰器,使其可以在异步环境中被调用
web_ui_result = Web_ui_result.objects
with transaction.atomic():
# 使用传入的 data 数据进行对象的创建
# 利用transaction.atomic() 确保数据库操作的原子性
# 通过这三个步骤,处理了playwright在执行过程中由于进程阻塞使用所导致的django orm 操作数据入库出现的数据集丢失,报错
# 此处可以处理自己想要的操作
print(result)