2016-12-13 6 views
0

リクエストが終了した後でもクエリされたテーブルがまだロックされていて、イベントループを停止するまで "切り捨て"を実行できないことがコンテキストマネージャの「with」内部でSQL文を実行することに気付きました。ここでコンテキストマネージャを使用している場合でもaiomysqlがテーブルをロックするのはなぜですか?

は、私のコードの例です:

import logging 
import asyncio 
import aiomysql 
from aiohttp import web 
from aiomysql.cursors import DictCursor 


logging.basicConfig(level=logging.DEBUG) 

async def index(request): 
    async with request.app["mysql"].acquire() as conn: 
     async with conn.cursor() as cur: 
      await cur.execute("SELECT * FROM my_table") 
      lines = await cur.fetchall() 

    return web.Response(text='Hello Aiohttp!') 

async def get_mysql_pool(loop): 
    pool = await aiomysql.create_pool(
     host="localhost", 
     user="test", 
     password="test", 
     db="test", 
     cursorclass=DictCursor, 
     loop=loop 
    ) 

    return pool 

if __name__ == "__main__": 
    loop = asyncio.get_event_loop() 
    mysql = loop.run_until_complete(get_mysql_pool(loop)) 
    app = web.Application(loop=loop, debug=True) 
    app["mysql"] = mysql 
    app.router.add_get("/", index) 
    web.run_app(app) 

カール「http://localhost:8080/」を実行した後、私はMySQLのCLIを使用してMySQLサーバに接続して実行「my_tableに切り捨てる」しようとしている - それがされるまで終了しません私はaiohttpを止める。この動作を変更するには?

答えて

1

デフォルトでは、接続がの自動コミットモードにないため、ロックが保持されます。 autocommit=Trueを追加すると問題が解決するはずです。

pool = await aiomysql.create_pool(
    host="localhost", 
    user="test", 
    password="test", 
    db="test", 
    autocommit=True, 
    cursorclass=DictCursor, 
    loop=loop) 

また、明示的なコマンドでトランザクションを解放することが可能である:ここではコンテキストマネージャの

await cur.execute("COMMIT;") 

主な目的は、トランザクションをコミットしていない、カーソルを閉じることです。

aiomysql取引のためのコンテキストマネージャをサポートしてSQLAlchemy.core拡張子を持って、ここでは例を参照してください。

https://github.com/aio-libs/aiomysql/blob/93aa3e5f77d77ad5592c3e9519cfc9f9587bf9ac/tests/pep492/test_async_with.py#L214-L234

+0

は、私があまりにもSELECTステートメントをコミットする必要があることを知りませんでした。 – offline15

関連する問題