2015-12-08 4 views
0

Я хочу сохранить вывод валютного API в таблице MySQL, используя SQLAlchemy и Tornado, но когда я перебираю результаты JSON, возвращаемый API и я вставляю каждый из них в базу данных, приложение застряло. Никакие другие процедуры не могут быть выполнены до тех пор, пока все вставки не будут завершены, когда это произойдет.Сохранение вывода API async с использованием SQLAlchemy и Tornado

Я предполагаю, что я должен выполнить вставку также как сопрограмму, но не уверен, как это сделать. Я знаю, что существует несколько библиотек для async 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() 

ответ

1

К сожалению SQLAlchemy не ASync, каждый запрос (операции) к БД будет блокировать. Более того, концепция ORM затрудняет работу асинхронно (ref: How to make SQLAlchemy in Tornado to be async?).

Вы, возможно, заинтересованы в проектах (асинхронный):

  • momoko - Postgres Торнадо-клиента, это не ORM,
  • aiopg - Postgres asyncio основанного клиент (Tornado 4,3 и выше), поддержка SQLAlchemy строителей запросов
  • tornado-mysql - MySQL Tornado-клиент

Подсказка:

response = yield http_client.fetch(url) 
if response.error: 
    raise tornado.web.HTTPError(500) 

Уступка также приведет к возникновению ошибки HTTPError при ошибке, поэтому явный рейз не нужен.

+0

Спасибо kAlmAcetA! Asyncio отлично смотрится, так как я смогу использовать SQLAlchemy. Спасибо за подсказку кстати :) – user3159821

Смежные вопросы