tornado + tormysql 异步使用数据库 提高并发能力

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yangxiaodong88/article/details/86519110

基础

https://blog.csdn.net/yangxiaodong88/article/details/86494125
本篇文章已经讲解了怎么基础使用tormysql 异步客户端去操作mysql

封装前的demo

主要是在 db_base 里面对增删
demo 获取集合的sql

     @classmethod
    async def get_10(cls):
        async with await pool.Connection() as conn:
            async with conn.cursor() as cursor:
                data = dict()
                data["state"] = 1
                data["approval_state"] = 3
                data["parent_id"] = "NULL"
                dd = ["4eb1c040f14111e8870c509a4c9436be", "d5fe1550f13a11e8ab55509a4c9436be"]
                data["situation_id"] = tuple(dd)
                # sql = "SELECT id,created_at,content FROM comment where  state={state} and approval_state !='{approval_state}' and parent_id IS NULL and situation_id in {situation_id}"
                sql = "SELECT id,created_at,content FROM comment where  state={state} and approval_state !='{approval_state}' and parent_id IS {parent_id} and situation_id in {situation_id}"
                # sql = "SELECT id,created_at,content FROM comment WHERE parent_id is NULL "
                sql = sql.format(**data)
               
                await cursor.execute(sql)
                data = cursor.fetchall()
                
        return data

    @classmethod
    async def get(cls):
        async with await pool.Connection() as conn:
            async with conn.cursor() as cursor:
                # data = dict()
                # data["db_name"] = "ohho_configuration"
                # data["timestamp"] = "timestamp"
                # data["identity"] = "identity"
                # sql = "SELECT {timestamp},{identity} FROM {db_name} "
                # sql = sql.format(**data)
                # await cursor.execute(sql)
                # data = cursor.fetchone()

                data = dict()
                data["db_name"] = "configuration"
                data["aa"] = "timestamp" + "," + "identity"
                # field_list = ["timestamp", "identity"] # ok
                # field_list = ["*"] # ok
                field_list = ["timestamp as tt", "identity"]  # ok
                field_list = ["sum(threshold) as thr"]  # ok 可以有哈哈
                field_list = ["identity", "threshold"]  # ok 可以有哈哈
                data["field"] = ",".join(field_list)
                # condition = "threshold >100"  # 可行
                condition = "threshold >100 order by threshold desc"  # 可行 perfect
                condition = "id in(1,3,4)"  # ok
                condition = "description in('信誉积分下限')"  # 真棒
                # ======
                # ids = [1, 3, 5]
                # ids = tuple(ids)
                # condition = "id in {ids}".format(ids=ids)  # 真棒
                ###======= 可行
                # a = 1, 2, 3  # 这种可以
                a = [1, 3, 5]

                # ids = [1]
                # ids = ",".join(ids)
                # ids = tuple(ids)
                # ids = (1)  # 这个不可以
                # condition = "id in {ids}".format(ids=ids)  # 真棒
                # condition = "id in (1)"  # 真棒 这个可以
                # condition = "id in {ids}".format(ids=ids)  # 真棒 这个可以
                # condition = "id in {ids}".format(ids=a)  # 真棒 这个可以
                def get_in_data(data_):
                    if isinstance(data_, list):
                        if len(data_) > 1:
                            data_ = tuple(data_)
                        elif len(data_) == 1:
                            data_ = "(" + str(data_[0]) + ")"
                    return data_

                # ids = [1, 3, 5]
                ids = [1]
                ids = get_in_data(ids)
                # ids = tuple(ids)
                condition = "id in {ids}".format(ids=ids)  # 真棒 这个可以
                data["condition"] = condition
                # sql = "SELECT {field} FROM {db_name} WHERE {condition}"
                sql = "SELECT {field} FROM {db_name} WHERE {condition}"
                sql = sql.format(**data)
                await cursor.execute(sql)
                data = cursor.fetchall()
                # data = cursor.fetchone()
        return data

以上是读取数据的 demo, 注意:再有in这样后面带()的时候拼接字符串的时候要特别注意, 字段上面是没有“” 的 在条件语句等都有。in 后面的拼接当时坑了很久。当出现问题的时候使用简单的demo测试, 测试结果比较容易得出。

更新demo

@classmethod
    async def update_data(cls):
        async with await pool.Connection() as conn:
            async with conn.cursor() as cursor:
                db_name = "school"
                set_data = dict()
                set_data["name"] = "你知道的"
                set_field = "name='{name}'"
                set_field = set_field.format(**set_data)
                condition = "id = '2b65e14c-10cd-11e9-b36b-509a4c9436be'"
                data = dict()
                data["db_name"] = db_name
                data["set_field"] = set_field
                data["condition"] = condition
                sql = "UPDATE {db_name} SET {set_field}  where {condition}"

                sql = sql.format(**data)
                await cursor.execute(sql)
        return

添加demo

 @classmethod
    async def add_new(cls):
        async with await pool.Connection() as conn:
            flag = True
            try:
                async with conn.cursor() as cursor:
                    c1 = uuid.uuid1()
                    # c1 = "op"
                    data_ = dict()
                    data_["id"] = str(c1) # 不加str() 在这个列表里会报错
                    data_["name"] = "湖北 hello"
                    data = dict()
                    # field = "id, name"

                    data["field"] = ",".join(list(data_.keys()))
                    values = ["'" + str(d) + "'" for d in data_.values()]
                    data["values"] = ",".join(values)
                    data["db_name"] = "school"
                    # sql = "INSERT INTO school({field}) VALUES('{id}', '{name}')".format(**data)  # 可以的
                    # sql = "INSERT INTO school({field}) VALUES({values})".format(**data)  #
                    sql = "INSERT INTO {db_name}({field}) VALUES({values})".format(**data)  # 
                    await cursor.execute(sql)
            except Exception as e:
                await conn.rollback()
                flag = False
            else:
                await conn.commit()

        return flag

删除demo

   @classmethod
    async def delete_some(cls):
        async with await pool.Connection() as conn:
            async with conn.cursor() as cursor:
                data = dict()
                data["db_name"] = "school"
                data["condition"] = "id='819df450-197e-11e9-991e-509a4c9436be'"
                sql = "delete from {db_name} WHERE {condition}".format(**data)
                await cursor.execute(sql)

        return ""

现在开始封装demo 的整理展示

from yang_test.common.connect_pool import pool
from yang_test.common.base_model import BaseModel


# class DBBase(BaseModel):
class DBBase():
    def __init__(self, conn=None, db_name=None):
        self.conn = conn
        self.db_name = db_name

    def get_delete_sql(self, condition=None):
        """
        获取删除的sql
        :param condition: 删除的条件 (字符串)
        :return: 返回删除语句
        """
        data = dict()
        data["db_name"] = self.db_name
        if condition:
            data["condition"] = condition
            sql = "delete from {db_name} WHERE {condition}".format(**data)
        else:
            sql = "delete from {db_name}".format(**data)
        return sql

    def get_add_sql(self, data=None):
        """
        获取添加sql
        :param data: 字典类型数据 (dict)
        :return:
        """
        if not data:
            return False
        data_data = dict()
        data_data["db_name"] = self.db_name
        data_data["fields"] = ",".join(list(data.keys()))
        values = ["'" + str(d) + "'" for d in data.values()]
        data_data["values"] = ",".join(values)
        sql = "INSERT INTO {db_name}({field}) VALUES({values})".format(**data)
        return sql

    def get_update_sql(self, set_field=None, condition=None):
        """
        获取更新 数据的sql
        :param set_field: 要设置的字段 (字符串)
        :param condition: 判断的条件 (字符串)
        :return: 返回 return
        """
        if not set_field:
            return False
        data = dict()
        data["db_name"] = self.db_name
        data["set_field"] = set_field
        if condition:
            data["condition"] = condition
            sql = "UPDATE {db_name} SET {set_field}  where {condition}"
        else:
            sql = "UPDATE {db_name} SET {set_field}"

        sql = sql.format(**data)
        return sql

    def get_select_sql(self, field_list=None, condition=None):
        """
        获得查询sql
        传入field_list 必须为list 列表
        :param db_name: 数据库的名字 (字符串)
        :param condition: 条件语句 字符串 (字符串)
        :param field_list: 字段列表, 操作动作想要的字段 (列表)
        :return:
        """
        field = ",".join(field_list) if field_list else "*"
        data = dict()
        data["field"] = field
        data["db_name"] = self.db_name
        if condition:
            data["condition"] = condition
            sql = "SELECT {field} FROM {db_name} WHERE {condition}"
        else:
            sql = "SELECT {field} FROM {db_name}"
        sql = sql.format(**data)
        return sql

    def get_in_data(self, data_):
        """为了解决 条件中有 in 的情况 拼接in 中数据的时候
        当列表 为一个的时候 tuple() 会是(1,)的效果, 在in 语句中会出错的
        这个方法就是为了 让拼接者不去考虑处理逻辑直接传入 一个列表 就可以不管是 长度是1 还是大于1
        """
        if isinstance(data_, list):
            if len(data_) > 1:
                data_ = tuple(data_)
            elif len(data_) == 1:
                data_ = "(" + str(data_[0]) + ")"
        return data_

    async def update_data(self, sql):
        """更新数据"""
        async with await pool.Connection() as conn:
            async with conn.cursor() as cursor:
                await cursor.execute(sql)
        return ""

    async def get_many(self, sql, n):
        """获取 多条数据"""
        async with await pool.Connection() as conn:
            async with conn.cursor() as cursor:
                await cursor.execute(sql)
                data = cursor.fetchmany(n)
        # return data
        return BaseModel.query(data)

    async def get_all(self, sql):
        """获取 所有数据"""
        async with await pool.Connection() as conn:
            async with conn.cursor() as cursor:
                await cursor.execute(sql)
                data = cursor.fetchall()
        return BaseModel.query(data)

    async def delete_data(self, sql):
        """删除"""
        async with await pool.Connection() as conn:
            async with conn.cursor() as cursor:
                await cursor.execute(sql)
        return ""

    async def get_one(self, sql):
        """获取一条数据"""
        async with await pool.Connection() as conn:
            async with conn.cursor() as cursor:
                await cursor.execute(sql)
                data = cursor.fetchone()
        return BaseModel.query(data)

    async def add_one(self, sql):
        """插入一条数据"""
        flag = True
        async with await pool.Connection() as conn:
            try:
                async with conn.cursor() as cursor:
                    await cursor.execute(sql)
            except Exception as e:
               
                await conn.rollback()
                flag = False
            else:
                await conn.commit()
        return flag

获得各种sql 语句和执行 sql 语句都是在这个父类中实现, 每一基类都继承这样的一个父类, 调用 时候方面, 在每一个子类中去 传入你需要的字段 和 sql语句,在创建db的时候就将这个db要操作的mysql,

调用实例的demo

DB_NAME = "club_member"


class ClubMember(DBBase):
    def __init__(self):
        super(ClubMember, self).__init__(conn=conn, db_name=DB_NAME)

    async def get_one_by_user(self, user_id):
        field = ["*"] # 想需要的字段列表, eg:field_list = ["sum(threshold) as thr"],field_list = ["identity", "threshold"]
        data = dict()
        data["user_id"] = user_id
        data["state"] = STATE_DEFAULT
        condition = "user_id='{user_id}' and state='{state}' order by created_at desc"
        condition = condition.format(**data) # 拼接的where后面的条件字符串语句
        sql = self.get_select_sql(field, condition)       
        one = await self.get_one(sql)
        return one

说明:
这样封装 调用的时候, 调用者值需要关心自己需要的字段,需要的条件语句 就可以获得锁需要的sql 然后根据自己的需求去执行sql 是想要所有的还是 几个 亦或者是一个。只需要在建立这个db 文件的时候传入父类中的数据库name 就可以, 已不用每个方法去写很多的select 这样的样板代码。 调用者只关心自己需要的, 字段+条件 (字段列表, 字符串 条件)

有点:

  • 只需要 关心需要字段和条件语句
  • 减少了很多的样板代码
  • 对象的封装 也能正常的使用对象调用的方式
  • 操作数据库 的开发效率也比较高

猜你喜欢

转载自blog.csdn.net/yangxiaodong88/article/details/86519110