异步函数中的 PyMySql 查询

PyMySql query in async function

我正在使用 tornado 框架编写非阻塞 API。

我想进行异步 mysql 查询,为此我应该使用异步 mysql 库(用于龙卷风)还是可以使用类似这样的东西?

import tornado.web
import pymysql
import json


class AsyncDBCalls(tornado.web.RequestHandler):
    def initialize(self):
        database = {
            "host": "localhost",
            "user": "root",
            "password": "123456",
            "db": "tableName",
            "cursorclass": pymysql.cursors.DictCursor,
            "autocommit": True,
            "charset": "utf8"
        }
        try:
            self.db_connection = pymysql.connect(**database)
            self.db = self.db_connection.cursor()
        except pymysql.err.OperationalError:
            pass
            # TODO logging

    async def make_query(self, query):
        self.db.execute(query)
        results = self.db.fetchall()
        return results

    @tornado.web.asynchronous
    async def get(self):
        query = "SELECT * FROM users"
        results = await self.make_query(query)
        self.set_status(200)
        self.add_header("Content-Type", "text/json")
        self.write(json.dumps(results))
        self.finish()

这个make_query函数运行是异步的吗?此代码是否可用于非阻塞 API?

改用TorMySQL

您还应该考虑使用连接池,因为您将不得不使用多个连接:

self.pool = tormysql.ConnectionPool(
        max_connections=256,
        wait_connection_timeout=5,
        idle_seconds=7200,
        host=<host>,
        db=<database>,
        user=<user>,
        passwd=<password>,
        cursorclass=tormysql.cursor.DictCursor,
        autocommit=True,
        use_unicode=True,
        charset="utf8",
        **kwargs
    )

connection = yield self.pool.Connection()
...
# this actually will not close the connection, but put back into pool
connection.close()

你可以偷这个gist。它将为您处理池。有了它,您可以:

db.query("SELECT ..");

对于原子操作,或者从池中获取连接以获得更复杂的东西:

with (yield db.acquire(auto_commit=False)) as db:
    row = yield db.get("SELECT ... FOR UPDATE");
    ...
    yield db.execute("UPDATE ...");
    yield db.commit()