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
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
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)
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
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
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
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