Beispiel #1
0
 def query_count(self, cnx=None, **kwargs) -> list:
     """
     
     数据库小助手-查询数据的条数\n
     :param cnx: 数据连接,装饰器自动赋值
     :param kwargs: 可以识别的关键字参数:sql,如果存在,就直接使用sql进行查询
         如果不存在,那么使用指定了表名和查询字段和条件的查询方式
     :return: 将查询的数据以[{}]的形式返回\n
     """
     count = 0
     # cnx = self.get_cnx()
     cursor = cnx.cursor()
     sql = kwargs.get('sql')
     if sql is not None:
         MySQLHelper.execute(cursor=cursor, sql=sql)
     else:
         tablename = kwargs.get('tablename')
         ql = kwargs.get('query_list')
         if not tablename:
             raise NFLError('如果没有传sql,必须传tablename')
         sql = 'select count(*) from ' + tablename
         where, params = MySQLHelper.generate_where(ql)
         cursor.execute(sql + where, params)
     count = cursor.fetchone()[0]
     # cnx.close()
     return count
Beispiel #2
0
    def query(self, cnx=None, **kwargs) -> list:
        """

        数据库小助手-查询
        \n:param cnx: 数据连接,装饰器自动赋值
        \n:param kwargs: 可以识别的关键字参数:sql,如果存在并且含有placeholder %s,则必须存在params就直接使用sql进行查询
            如果不存在,那么使用指定了表名和查询字段和条件的查询方式
        \n:return: 将查询的数据以[{}]的形式返回\n
        """
        result = []
        # cnx = self.get_cnx()
        sql = kwargs.get('sql')
        params = kwargs.get('params')
        cursor = cnx.cursor(dictionary=True)
        if sql is not None:
            MySQLHelper.execute(cursor=cursor, sql=sql, params=params)
        else:
            tablename = kwargs.get('tablename')
            ql = kwargs.get('query_list')
            if not tablename:
                raise NFLError('如果没有传sql,必须传tablename')
            sql = 'select * from ' + tablename
            where, params = MySQLHelper.generate_where(ql)
            cursor.execute(sql + where, params)
        for row in cursor:
            result.append(row)
        return result
Beispiel #3
0
 def execute(cursor=None, sql=str, params=tuple) -> str:
     if '%s' in sql:
         if not params:
             raise NFLError("如果使用sql,且sql中有占位符号,则必须传递params参数")
         else:
             cursor.execute(sql, params)
     else:
         cursor.execute(sql)
Beispiel #4
0
    def update(self, cnx=None, **kwargs) -> int:
        """

        数据库小助手-更新\n
        :param cnx: 数据库连接,装饰器自动赋值
        :param kwargs: 可以识别的关键字参数:sql,如果存在,就直接使用sql进行更新操作
            如果不存在,那么使用指定了表名和更新字段和条件的更新方式
        :return: 将更新的行数予以返回
        """
        row = 0
        # cnx = self.get_cnx()
        cursor = cnx.cursor()
        sql = kwargs.get('sql')
        params = kwargs.get('params')
        try:
            if sql is not None:
                MySQLHelper.execute(cursor=cursor, sql=sql, params=params)
            else:
                tablename = kwargs.get('tablename')
                params = {}
                ul = kwargs.get('update_list')
                ql = kwargs.get('query_list')
                if not tablename:
                    raise NFLError('如果没有传sql,必须传tablename')
                if not ul:
                    raise NFLError('更新语句params必须有update_list<QueryDictList>字段')
                assert isinstance(ul, QueryDictList)
                sql = 'UPDATE ' + tablename + ' SET '
                updates = ', '.join(
                    [ud.key + '=%(' + ud.key + ')s' for ud in ul])
                params = {ud.key: ud.value for ud in ul}
                where, ql_params = MySQLHelper.generate_where(ql=ql)
                params.update(ql_params)
                # print(sql + updates + where)
                cursor.execute(sql + updates + where, params)
            row = cursor.rowcount
            cnx.commit()
        except IntegrityError as e:
            print(e, file=sys.stderr)
            print(params)
        # cnx.close()
        return row
Beispiel #5
0
    def delete(self, cnx=None, **kwargs) -> int:
        """

                数据库小助手-删除\n
                :param cnx: 数据库连接,装饰器自动赋值
                :param kwargs: 可以识别的关键字参数:sql,如果存在,就直接使用sql进行更新操作
                    如果不存在,那么使用指定了表名和条件的删除方式
                :return: 将删除的行数予以返回
                """
        row = 0
        # cnx = self.get_cnx()
        cursor = cnx.cursor()
        sql = kwargs.get('sql')
        params = kwargs.get('params')
        try:
            if sql is not None:
                MySQLHelper.execute(cursor=cursor, sql=sql, params=params)
            else:
                tablename = kwargs.get('tablename')
                params = {}
                ql = kwargs.get('query_list')
                if not tablename:
                    raise NFLError('如果没有传sql,必须传tablename')
                if not ql:
                    raise NFLError('更新语句params必须有query_list<QueryDictList>字段')
                assert isinstance(ql, QueryDictList)
                sql = 'DELETE FROM ' + tablename
                where, params = MySQLHelper.generate_where(ql=ql)
                # print(sql + where)
                cursor.execute(sql + where, params)
            row = cursor.rowcount
            cnx.commit()
        except IntegrityError as e:
            print(e, file=sys.stderr)
            print(params)
        # cnx.close()
        return row
Beispiel #6
0
    def insert(self, cnx=None, **kwargs) -> tuple:
        """

        数据库小助手-插入
        \n:param cnx: 数据库连接,装饰器自动赋值
        \n:param kwargs: 可以识别的关键字参数:sql,如果存在,就直接使用sql进行插入操作
            如果不存在,那么使用指定了表名和查询字段和条件的查询方式
        \n:return: 将插入的行数予以返回
        """
        row = 0
        rowid = None
        # cnx = self.get_cnx()
        cursor = cnx.cursor()
        sql = kwargs.get('sql')
        params = kwargs.get('params')
        try:
            if sql is not None:
                MySQLHelper.execute(cursor=cursor, sql=sql, params=params)
            else:
                tablename = kwargs.get('tablename')
                params = {}
                ql = kwargs.get('query_list')
                ql_list = kwargs.get('ql_list')
                if not tablename:
                    raise NFLError('如果没有传sql,必须传tablename')
                if not ql:
                    if not ql_list or not len(ql_list):
                        raise NFLError(
                            '插入语句params必须有query_list<QueryDictList>字段,或者ql_list<list<QueryDictList>>字段'
                        )

                sql = 'INSERT INTO ' + tablename
                names = ' ('
                values = ' VALUES ('
                if ql:
                    assert isinstance(ql, QueryDictList)
                    names += ','.join([qd.key for qd in ql])
                    values += ','.join(['%(' + qd.key + ')s' for qd in ql])
                    params = {qd.key: qd.value for qd in ql}
                    values += ")"
                elif ql_list:
                    names += ','.join([qd.key for qd in ql_list[0]])
                    values = ' VALUES '
                    values += ',\n'.join([
                        '(' + ', '.join(value) + ')' for value in
                        [['%(' + qd.key + str(i) + ')s' for qd in ql]
                         for i, ql in enumerate(ql_list)]
                    ])
                    params = {
                        item[0].key + str(item[1]): item[0].value
                        for qdi in [[(qd, i) for qd in ql]
                                    for i, ql in enumerate(ql_list)]
                        for item in qdi
                    }

                names += ")"
                print(sql + names + values)
                cursor.execute(sql + names + values, params)
            row = cursor.rowcount
            rowid = cursor.lastrowid
            cnx.commit()
        except IntegrityError as e:
            print(e, file=sys.stderr)
            print(params)
        # cnx.close()
        return row, rowid
Beispiel #7
0
    def number2upper(self, num: int) -> str:
        """将输入的数字按照中文的书写方式返回(支持的数字长度是65536位数字)
        例如:
            123456789\n
            一亿二千三百四十五万六千七百八十九\n
            算法如下:
                算法采用的是上数法,数穷则变,就是:万万曰亿,亿亿曰兆,兆兆曰京...
                数字从右往左数,可以获取到每个数字的编号,起始编号为0\n
                用该位数字编号和4取模,若有余,余1为十,余2为百,余3为千\n
                若整除,则用该位数字编号与4整除,若结果为奇数,则该位单位为万\n
                若结果为偶数:
                    1: 先判断该结果是否是2的整数次方,若是,该位单位是CN_UNIT[次方]\n
                    2:若不是:从亿位开始作为检测标记位,用结果和(2^检测标记位下标)取余\n
                       若能整除,并且商为奇数则单位是 CN_INIT[标记检测位下标]

            另外,我这个方法支持的数字真的非常大,我可以不判断数字长度吗?
            每添加一个更大的单位在上面的UN_UNIT列表的最后面,您就可以将当前的长度扩充一倍\n
            添加方法:n2u.append_unit('更大的单位')

        :param num: 一个整型数字
        :return: 返回数字的中文书写方式
        """
        def cal_unit(num_index: int) -> str:
            """计算对应编号数字的单位

            :param num_index: 数字的编号,指的是数字中的某一位数字在该数字中从右往左数的编号,编号从0开始\n
            :return: 返回指定编号位数字的单位
            """
            if num_index == 0:  # 如果数字为个位,没有单位
                return ''
            remain = num_index % 4
            if remain > 0:
                if remain == 1:
                    return '十'
                elif remain == 2:
                    return '百'
                elif remain == 3:
                    return '千'
            else:
                consult_4 = num_index // 4
                if consult_4 % 2 != 0:
                    return '万'
                else:
                    bin_consult_4 = bin(consult_4)
                    c1_bin_consult_4 = bin_consult_4.split('b')[1].count('1')
                    c0_bin_consult_4 = bin_consult_4.split('b')[1].count('0')
                    if c1_bin_consult_4 == 1:
                        return self.__CN_UNIT[c0_bin_consult_4]
                    else:
                        for check_index in range(1, len(self.__CN_UNIT)):
                            if consult_4 % (2**check_index) == 0:
                                checked_consult_4 = consult_4 // (2**
                                                                  check_index)
                                if checked_consult_4 % 2 != 0:
                                    return self.__CN_UNIT[check_index]

        # 首先验证输入的数字是否合法
        if not isinstance(num, int):
            raise NFLError('您输入的数字不是整数吧,我只能支持整数,我在正在努力学习,嘤嘤嘤')
        upper_num = ''
        # 首先将数字转换成单个数字的列表
        num_list = [int(str_num) for str_num in str(num)]
        len_num = len(num_list)
        max_len = 2**(len(self.__CN_UNIT) + 2)
        if len_num > max_len:
            raise NFLError('您输入的数字太长了,我只能支持' + str(max_len) + '位数字,嘤嘤嘤')
        for i in range(len_num):
            num_bit = num_list[i]

            i_index = len_num - i - 1
            # 根据算法计算出单位
            unit = cal_unit(i_index)
            # 如果首位数字为1并且为十位,则一可不写

            # 处理该位数字是0的情况
            if num_bit == 0:
                if self.__CN_UNIT.count(unit) == 1:
                    """数字为0,但是该位数字的单位是CN_UNIT中的一个的情况\n
                        如果前一位是零,则删除零
                            这里会有一种极端情况,如果接下的超过四位数都为零,则会出现两个单位碰到一起\n
                            这时候就在末尾用零代替第二个单位
                    """
                    if upper_num.endswith('零'):
                        upper_num = upper_num.rstrip('零')
                        # 默认单位长度为一,处理单位长度大于一的情况
                        stop = -2
                        last_unit = upper_num[-1:stop:-1][::-1]
                        while not [
                                '十', '百', '千'
                        ].count(last_unit) and not self.__CN_UNIT.count(
                                last_unit):
                            stop -= 1
                            last_unit = upper_num[-1:stop:-1][::-1]
                        if self.__CN_UNIT.count(last_unit):
                            if self.__CN_UNIT.index(
                                    unit) - self.__CN_UNIT.index(
                                        last_unit) < 1:
                                upper_num += '零'
                                continue
                    upper_num += unit
                else:  # 如果数字为零并且不在上述单位,并且前一位不是零,则加上零
                    if not upper_num.endswith('零'):
                        upper_num += self.__CN_NUM[num_bit]
            else:  # 数字不是零的情况就加上转换后的大写数字和单位
                if not (unit == '十' and i == 0
                        and num_bit == 1):  # 若首位数字为1并且该位为十位就不需要一
                    upper_num += self.__CN_NUM[num_bit]
                upper_num += unit
        if len(upper_num) > 1:
            upper_num = upper_num.rstrip('零')
        return upper_num