我想使用SQLAlchemy和Tornado将货币API的输出保存在MySQL表中但是当我循环JSON结果时,API返回并且我将每个API插入数据库,应用程序卡住了。在发生这种情况时,在完成所有插入之前,不能执行任何其他过程。
我想我也应该像协程一样执行插入,但不知道该怎么做。我知道有几个用于异步SQLAlchemy的库,例如Asyncio但是在使用Tornado时它们真的需要吗?
下面的代码在底部和Currency_rate
执行循环时阻塞from datetime import datetime
from decimal import Decimal
import urllib
import tornado.web
import tornado.httpclient
from tornado import gen
from src.entities.currency import list_currencies, view_iso_a3_currency
from src.entities.currency_rate import Currency_rate
@gen.coroutine
def currencylayer_currency_rate():
http_client = tornado.httpclient.AsyncHTTPClient()
base_url = "http://apilayer.net/api/live?"
base_currency = view_iso_a3_currency('USD')
vars = {'access_key': 'APIKEY', 'source': base_currency.iso_a3, 'format': 1}
url = base_url + urllib.parse.urlencode(vars)
response = yield http_client.fetch(url)
if response.error:
raise tornado.web.HTTPError(500)
json = tornado.escape.json_decode(response.body)
timestamp = datetime.fromtimestamp(int(json['timestamp'])).strftime('%Y-%m-%d %H:%M:%S')
json_rates = json['quotes']
for key, value in json_rates.items():
quote_currency = view_iso_a3_currency(str(key)[-3:])
if not quote_currency:
continue
currency_rate = Currency_rate(m_currency_id1 = base_currency.id,
m_currency_id2 = quote_currency.id,
rate = Decimal(value),
date = timestamp,
create_user = 1,
update_user = 1,
active = 1)
currency_rate.add()
答案 0 :(得分:1)
不幸的是,SQLAlchemy不是异步的,每个db的请求(操作)都会阻塞。更重要的是,ORM的概念很难让它异步工作(参考:How to make SQLAlchemy in Tornado to be async?)。
您可能对项目感兴趣(异步):
提示:
response = yield http_client.fetch(url)
if response.error:
raise tornado.web.HTTPError(500)
产量也会在出错时引发HTTPError,因此显式加注是不必要的。