mdbq 2.9.3__py3-none-any.whl → 2.9.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
mdbq/mysql/mysql.py CHANGED
@@ -132,6 +132,7 @@ class MysqlUpload:
132
132
 
133
133
  return wrapper
134
134
 
135
+ @try_except
135
136
  def dict_to_mysql(self, db_name, table_name, dict_data, icm_update=None, main_key=None, unique_main_key=None, index_length=100, set_type=None):
136
137
  """
137
138
  插入字典数据
@@ -294,15 +295,18 @@ class MysqlUpload:
294
295
  if unique_main_key:
295
296
  for col in unique_main_key:
296
297
  del dict_data[col]
297
- update_datas = ', '.join([f'{k} = VALUES({k})' for k, v in dict_data.items()])
298
+ # 涉及列名务必使用反引号
299
+ update_datas = ', '.join([f'`{k}` = VALUES(`{k}`)' for k, v in dict_data.items()])
298
300
 
299
301
  # 构建 sql
300
302
  sql = f"INSERT INTO %s (%s) VALUES (%s) ON DUPLICATE KEY UPDATE %s" % (table_name, keys_data, values_data, update_datas)
303
+ # print(sql)
301
304
  cursor.execute(sql)
302
305
  connection.commit() # 提交数据库
303
306
  connection.close()
304
307
 
305
308
  def cover_dict_dtypes(self, dict_data):
309
+ """ 清理字典键值 并转换数据类型 """
306
310
  if not dict_data:
307
311
  print(f'mysql.py -> MysqlUpload -> cover_dict_dtypes -> 传入的字典不能为空')
308
312
  return
@@ -329,10 +333,14 @@ class MysqlUpload:
329
333
  count_int, count_float = count_decimal_places(v) # 判断小数,返回小数位数
330
334
  if result1: # 京东sku/spu商品信息
331
335
  __res_dict.update({k: 'mediumtext'})
336
+ elif k == '日期':
337
+ __res_dict.update({k: 'DATE'})
338
+ elif k == '更新时间':
339
+ __res_dict.update({k: 'TIMESTAMP'})
332
340
  elif str(v) == '':
333
341
  __res_dict.update({k: 'mediumtext'})
334
342
  elif result2: # 小数
335
- __res_dict.update({k: 'decimal(10,4)'})
343
+ __res_dict.update({k: 'decimal(12,4)'})
336
344
  elif date_type == 1: # 纯日期
337
345
  __res_dict.update({k: 'DATE'})
338
346
  elif date_type == 2: # 日期+时间
@@ -345,7 +353,7 @@ class MysqlUpload:
345
353
  v = round(float(v), 4)
346
354
  __res_dict.update({k: 'decimal(12,4)'})
347
355
  elif count_float >= 6:
348
- __res_dict.update({k: 'decimal(12,6)'})
356
+ __res_dict.update({k: 'decimal(14,6)'})
349
357
  elif count_float >= 4:
350
358
  __res_dict.update({k: 'decimal(10,4)'})
351
359
  else:
@@ -355,12 +363,78 @@ class MysqlUpload:
355
363
  new_dict_data.update({k: v})
356
364
  return __res_dict, new_dict_data
357
365
 
366
+ def cover_df(self, df):
367
+ """ 清理 df 的值和列名 """
368
+ df.replace([np.inf, -np.inf], 0, inplace=True) # 清理一些非法值
369
+ df.replace(to_replace=['\\N', '-', '--', '', 'nan', 'NAN'], value=0, regex=False, inplace=True) # 替换掉特殊字符
370
+ df.replace(to_replace=[','], value='', regex=True, inplace=True)
371
+ df.replace(to_replace=['="'], value='', regex=True, inplace=True) # ="和"不可以放在一起清洗, 因为有: id=86785565
372
+ df.replace(to_replace=['"'], value='', regex=True, inplace=True)
373
+ cols = df.columns.tolist()
374
+ for col in cols:
375
+ df[col] = df[col].apply(lambda x: float(re.sub(r'%$', '', str(x))) / 100 if (
376
+ str(x) != '' and str(x).endswith('%')) else '0.0' if str(x) == '0%' else x)
377
+ try:
378
+ df[col] = df[col].apply(
379
+ lambda x: int(x) if '_' not in str(x) and '.' not in str(x) else x) # 不含小数点尝试转整数
380
+ except:
381
+ pass
382
+ if df[col].dtype == 'object':
383
+ try:
384
+ df[col] = df[col].apply(lambda x: float(x) if '.' in str(x) and '_' not in str(x) else x)
385
+ except:
386
+ pass
387
+ new_col = col.lower()
388
+ new_col = re.sub(r'[()\-,,&~^、 ()\"\'“”=·/。》《><!!`]', '_', new_col, re.IGNORECASE)
389
+ new_col = new_col.replace(')', '')
390
+ new_col = re.sub(r'_{2,}', '_', new_col)
391
+ new_col = re.sub(r'_+$', '', new_col)
392
+ df.rename(columns={col: new_col}, inplace=True)
393
+ df.fillna(0, inplace=True)
394
+ return df
395
+
396
+ def convert_df_dtypes(self, df: pd.DataFrame):
397
+ """ 清理 df 的值和列名,并转换数据类型 """
398
+ df = self.cover_df(df=df) # 清理 df 的值和列名
399
+ [pd.to_numeric(df[col], errors='ignore') for col in df.columns.tolist()]
400
+ dtypes = df.dtypes.to_dict()
401
+ __res_dict = {}
402
+ for k, v in dtypes.items():
403
+ result1 = re.findall(r'编码|_?id|货号|款号|文件大小', k, re.IGNORECASE)
404
+ result2 = re.findall(r'占比$|投产$|产出$|roi$|率$', k, re.IGNORECASE)
405
+ result3 = re.findall(r'同比$|环比$', k, re.IGNORECASE)
406
+ result4 = re.findall(r'花费$|消耗$|金额$', k, re.IGNORECASE)
407
+
408
+ if result1: # id/sku/spu商品信息
409
+ __res_dict.update({k: 'varchar(50)'})
410
+ elif result2: # 小数
411
+ __res_dict.update({k: 'decimal(10,4)'})
412
+ elif result3: # 小数
413
+ __res_dict.update({k: 'decimal(12,4)'})
414
+ elif result4: # 小数
415
+ __res_dict.update({k: 'decimal(12,2)'})
416
+ elif k == '日期':
417
+ __res_dict.update({k: 'DATE'})
418
+ elif k == '更新时间':
419
+ __res_dict.update({k: 'TIMESTAMP'})
420
+ elif v == 'int64':
421
+ __res_dict.update({k: 'int'})
422
+ elif v == 'float64':
423
+ __res_dict.update({k: 'decimal(10,4)'})
424
+ elif v == 'bool':
425
+ __res_dict.update({k: 'BOOLEAN'})
426
+ elif v == 'datetime64[ns]':
427
+ __res_dict.update({k: 'datetime'})
428
+ else:
429
+ __res_dict.update({k: 'varchar(255)'})
430
+ return __res_dict, df
431
+
358
432
  @try_except
359
- def df_to_mysql(self, df, table_name, db_name='远程数据源', icm_update=[], service_database={'xigua_lx': 'mysql'}, move_insert=False, df_sql=False, drop_duplicates=False, filename=None, count=None, json_path=None, reset_id=False):
433
+ def df_to_mysql(self, df, db_name, table_name, set_typ=None, icm_update=[], move_insert=False, df_sql=False, drop_duplicates=False,
434
+ filename=None, count=None, reset_id=False):
360
435
  """
361
- df 写入数据库
362
- db_name: 数据库名称
363
- table_name: 集合/表名称
436
+ db_name: 数据库名
437
+ table_name: 表名
364
438
  move_insert: 根据df 的日期,先移除数据库数据,再插入, df_sql, drop_duplicates, icm_update 都要设置为 False
365
439
  原则上只限于聚合数据使用,原始数据插入时不要设置
366
440
 
@@ -369,8 +443,6 @@ class MysqlUpload:
369
443
  icm_update: 增量更新, 在聚合数据中使用,原始文件不要使用,设置此参数时需将 drop_duplicates 改为 False
370
444
  使用增量更新: 必须确保 icm_update 传进来的列必须是数据表中唯一主键,值不会发生变化,不会重复,否则可能产生错乱覆盖情况
371
445
  filename: 用来追踪处理进度,传这个参数是方便定位产生错误的文件
372
- service_database: 这个参数是用来设置更新哪台服务器的 types 信息到本地 json 文件
373
- json_path: 这个参数同样也是是用来设置更新 json 文件
374
446
  """
375
447
  self.filename = filename
376
448
  if isinstance(df, pd.DataFrame):
@@ -384,8 +456,13 @@ class MysqlUpload:
384
456
  print(f'{db_name} 不能为 None')
385
457
  return
386
458
 
387
- cv = converter.DataFrameConverter()
388
- df = cv.convert_df_cols(df=df) # 清理 dataframe 非法值
459
+ # 清理 dataframe 非法值,并转换获取数据类型
460
+ dtypes, df = self.convert_df_dtypes(df)
461
+ if set_typ:
462
+ # 更新自定义的列数据类型
463
+ for k, v in dtypes.items():
464
+ # 确保传进来的 set_typ 键存在于实际的 df 列才 update
465
+ [dtypes.update({k: inside_v}) for inside_k, inside_v in set_typ.items() if k == inside_k]
389
466
 
390
467
  connection = pymysql.connect(**self.config) # 连接数据库
391
468
  with connection.cursor() as cursor:
@@ -415,10 +492,6 @@ class MysqlUpload:
415
492
  cursor.execute(sql)
416
493
  print(f'创建 mysql 表: {table_name}')
417
494
 
418
- for service_name, database in service_database.items():
419
- # 2. 列数据类型转换,将 df 数据类型转换为 mysql 的数据类型
420
- dtypes, cl, db_n, tb_n = self.convert_dtypes(df=df, db_name=db_name, table_name=table_name, path=json_path, service_name=service_name)
421
-
422
495
  # 有特殊字符不需转义
423
496
  sql = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s;"
424
497
  cursor.execute(sql, (db_name, table_name))
@@ -444,7 +517,8 @@ class MysqlUpload:
444
517
 
445
518
  if df_sql:
446
519
  now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ")
447
- print(f'{now}正在更新: mysql ({self.host}:{self.port}) {db_name}/{table_name}, {count}, {self.filename}')
520
+ print(
521
+ f'{now}正在更新: mysql ({self.host}:{self.port}) {db_name}/{table_name}, {count}, {self.filename}')
448
522
  engine = create_engine(
449
523
  f"mysql+pymysql://{self.username}:{self.password}@{self.host}:{self.port}/{db_name}") # 创建数据库引擎
450
524
  df.to_sql(
@@ -454,45 +528,23 @@ class MysqlUpload:
454
528
  index=False,
455
529
  chunksize=1000
456
530
  )
457
- # print(f'重置自增')
458
- # # 6. 重置自增列
459
- # try:
460
- # cursor.execute(f"SHOW COLUMNS FROM {table_name} LIKE 'id'")
461
- # result = cursor.fetchone()
462
- # if result:
463
- # cursor.execute(f"ALTER TABLE {table_name} DROP COLUMN id;") # 删除 id 列
464
- # cursor.execute(
465
- # f"ALTER TABLE {table_name} ADD column id INT AUTO_INCREMENT PRIMARY KEY FIRST;")
466
- # cursor.execute(f"ALTER TABLE {table_name} AUTO_INCREMENT = 1") # 设置自增从 1 开始
467
- # except Exception as e:
468
- # print(f'{e}')
469
- # connection.rollback()
470
-
471
- if cl and db_n and tb_n:
472
- mysql_types.mysql_all_dtypes(db_name=db_name, table_name=table_name) # 更新一个表的 dtypes
473
- elif cl and db_n:
474
- mysql_types.mysql_all_dtypes(db_name=db_name) # 更新一个数据库的 dtypes
475
- elif cl:
476
- mysql_types.mysql_all_dtypes() # 更新所有数据库所有数据表的 dtypes 信息到本地 json
477
-
531
+ if reset_id:
532
+ # 6. 重置自增列
533
+ try:
534
+ cursor.execute(f"SHOW COLUMNS FROM {table_name} LIKE 'id'")
535
+ result = cursor.fetchone()
536
+ if result:
537
+ cursor.execute(f"ALTER TABLE {table_name} DROP COLUMN id;") # 删除 id 列
538
+ cursor.execute(
539
+ f"ALTER TABLE {table_name} ADD column id INT AUTO_INCREMENT PRIMARY KEY FIRST;")
540
+ cursor.execute(f"ALTER TABLE {table_name} AUTO_INCREMENT = 1") # 设置自增从 1 开始
541
+ except Exception as e:
542
+ print(f'{e}')
543
+ connection.rollback()
544
+ connection.commit() # 提交事务
478
545
  connection.close()
479
546
  return
480
547
 
481
- # print(cl, db_n, tb_n)
482
- # 返回这些结果的目的是等添加完列再写 json 文件才能读到 types 信息
483
- # ⚠️ mysql_all_dtypes 函数默认只读取 xigua_lx 的数据库信息,不会读取其他系统
484
- if cl and db_n and tb_n:
485
- mysql_types.mysql_all_dtypes(db_name=db_name, table_name=table_name) # 更新一个表的 dtypes
486
- elif cl and db_n:
487
- mysql_types.mysql_all_dtypes(db_name=db_name) # 更新一个数据库的 dtypes
488
- elif cl:
489
- mysql_types.mysql_all_dtypes() # 更新所有数据库所有数据表的 dtypes 信息到本地 json
490
-
491
- # 4. 更新插入数据
492
- now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ")
493
- for service_name, database in service_database.items():
494
- print(f'{now}正在更新 mysql ({self.host}:{self.port}) {db_name}/{table_name}, {count}, {service_name}, {self.filename}')
495
-
496
548
  # 5. 移除指定日期范围内的数据,原则上只限于聚合数据使用,原始数据插入时不要设置
497
549
  if move_insert and '日期' in df.columns.tolist():
498
550
  # 移除数据
@@ -534,7 +586,6 @@ class MysqlUpload:
534
586
  # data 是传进来待处理的数据, 不是数据库数据
535
587
  # data 示例: {'日期': Timestamp('2024-08-27 00:00:00'), '推广费余额': 33299, '品销宝余额': 2930.73, '短信剩余': 67471}
536
588
  try:
537
-
538
589
  condition = []
539
590
  for k, v in data.items():
540
591
  condition += [f'`{k}` = "{v}"']
@@ -559,7 +610,8 @@ class MysqlUpload:
559
610
  cursor.execute(sql, (db_name, {table_name}))
560
611
  columns = cursor.fetchall()
561
612
  cols_exist = [col['COLUMN_NAME'] for col in columns] # 数据表的所有列, 返回 list
562
- update_col = [item for item in cols_exist if item not in icm_update and item != 'id'] # 除了主键外的其他列
613
+ update_col = [item for item in cols_exist if
614
+ item not in icm_update and item != 'id'] # 除了主键外的其他列
563
615
 
564
616
  # unique_keys 示例: `日期`, `余额`
565
617
  unique_keys = ', '.join(f"`{item}`" for item in update_col) # 列名需要转义
@@ -595,7 +647,8 @@ class MysqlUpload:
595
647
  if change_values: # change_values 有数据返回,表示值需要更新
596
648
  if not_change_col:
597
649
  not_change_values = [f'`{col}` = "{str(data[col])}"' for col in not_change_col]
598
- not_change_values = ' AND '.join(not_change_values) # 示例: `短信剩余` = '888' AND `test1` = '93'
650
+ not_change_values = ' AND '.join(
651
+ not_change_values) # 示例: `短信剩余` = '888' AND `test1` = '93'
599
652
  # print(change_values, not_change_values)
600
653
  condition += f' AND {not_change_values}' # 重新构建完整的查询条件,将未发生变化的列加进查询条件
601
654
  change_values = ', '.join(f"{item}" for item in change_values) # 注意这里 item 外面没有反引号
@@ -629,107 +682,6 @@ class MysqlUpload:
629
682
  connection.commit() # 提交事务
630
683
  connection.close()
631
684
 
632
- def convert_dtypes(self, df, db_name, table_name, path=None, service_name=None):
633
- """
634
- 根据本地 json 转换 df 的类型为 mysql 专有的数据类型
635
- 可能不存在本地 json 文件 (函数按指定规则转换并更新 json)
636
- 允许通过 json 文件手动添加或修改列的数据类型(仅影响初创数据表)
637
- """
638
- cols = df.columns.tolist()
639
- # path = set_support.SetSupport(dirname='support').dirname
640
- d = mysql_types.DataTypes(path=path, service_name=service_name)
641
- # 从本地文件中读取 dtype 信息
642
- dtypes, cl, db_n, tb_n = d.load_dtypes(cl='mysql', db_name=db_name, table_name=table_name)
643
- # 可能会因为没有 json 文件, 返回 None
644
- if dtypes:
645
- # 按照文件记录更新 dtypes
646
- dtypes.update({col: dtypes[col] for col in cols if col in dtypes.keys()})
647
- # 可能存在部分列不在文件记录中
648
- col_not_exist = [col for col in cols if col not in dtypes.keys()]
649
- # 这些列不存在于 df 中, 必须移除
650
- [dtypes.pop(col) for col in list(dtypes.keys()) if col not in cols]
651
- else: # 没有 json 文件时
652
- dtypes = df.dtypes.apply(str).to_dict() # 将 dataframe 数据类型转为字典形式
653
- col_not_exist = cols
654
- # 对文件不存在的列信息进行数据类型转换(按指定规则)
655
- dtypes.update({col: self.convert_dtype_to_sql(df=df, col=col, dtype=df[col].dtype) for col in col_not_exist})
656
- # print(dtypes)
657
- # 至此 df 中全部列类型已经转换完成
658
- # 返回结果, 示例: {'上市年份': 'mediumtext', '商品id': 'mediumtext', '平台': 'mediumtext'}
659
- return dtypes, cl, db_n, tb_n # 返回这些结果的目的是等添加完列再写 json 文件才能读到 types 信息
660
-
661
- def convert_dtype_to_sql(self, df, col, dtype):
662
- """ 按照以下规则转换DataFrame列的数据类型为 MYSQL 专有的数据类型 """
663
-
664
- def find_longest_decimal_value(number_list):
665
- # 针对小数设置的函数, 用来获取列表中小数位数最长的值
666
- longest_value = None
667
- max_decimals = 0
668
- for num in number_list:
669
- try:
670
- decimal_places = len(str(num).split('.')[1])
671
- if decimal_places > max_decimals:
672
- max_decimals = decimal_places
673
- longest_value = num
674
- except:
675
- longest_value = num
676
- continue
677
- return longest_value
678
-
679
- if '商品编码' in col: # 京东sku/spu商品信息
680
- return 'mediumtext'
681
- if '文件大小' in col: # bw 程序
682
- return 'mediumtext'
683
- if col.endswith('占比') and (df[col].dtype == 'float' or df[col].dtype == 'int'):
684
- return 'decimal(10,4)'
685
- elif dtype == 'datetime64[ns]':
686
- return 'DATETIME' # 使用 DATE 后续排重可能会引发不能排重
687
- elif dtype == 'int32':
688
- max_num = str(max(df[col].tolist()))
689
- if len(max_num) >= 10: # 数值长度超限转为 mediumtext
690
- return 'mediumtext'
691
- return 'INT'
692
- elif dtype == 'int64':
693
- max_num = str(max(df[col].tolist()))
694
- if len(max_num) >= 10:
695
- return 'mediumtext'
696
- return 'INT'
697
- elif dtype == 'float64':
698
- res = find_longest_decimal_value(df[col].tolist()) # 取小数位数最长的值
699
- if 'e' in str(res):
700
- res = round(float(res), 4)
701
- int_step = len(str(res).split('.')[0]) # 整数位数长度
702
- f_step = len(str(res).split('.')[1]) # 小数位数长度
703
-
704
- if int_step >= 12:
705
- return 'mediumtext' # mysql 中不要使用 float 和 double 类型,会影响计算结果
706
- elif int_step >= 8 and f_step >= 0:
707
- return 'decimal(16, 2)'
708
- elif int_step >= 6 and f_step >= 0:
709
- return 'decimal(10, 2)'
710
- elif int_step >= 4 and f_step >= 0:
711
- return 'decimal(10, 2)'
712
- elif int_step >= 2 and f_step >= 6:
713
- return 'decimal(12, 4)'
714
- elif int_step >= 2 and f_step > 4:
715
- return 'decimal(12, 4)'
716
- elif int_step >= 2 and f_step > 2:
717
- return 'decimal(10, 4)'
718
- elif int_step >= 2 and f_step >= 0:
719
- return 'decimal(10, 2)'
720
- elif int_step >= 1 and f_step >= 6:
721
- return 'decimal(12, 4)'
722
- elif int_step >= 1 and f_step > 4:
723
- return 'decimal(12, 4)'
724
- elif int_step >= 1 and f_step > 2:
725
- return 'decimal(10, 4)'
726
- else:
727
- return 'decimal(10, 2)'
728
- elif dtype == 'object':
729
- return 'mediumtext'
730
- else:
731
- return 'mediumtext'
732
-
733
685
  # @try_except
734
686
  def read_mysql(self, table_name, start_date, end_date, db_name='远程数据源', date_name='日期'):
735
687
  """ 读取指定数据表,可指定日期范围,返回结果: df """
@@ -1163,6 +1115,8 @@ if __name__ == '__main__':
1163
1115
  username, password, host, port = data['username'], data['password'], data['host'], data['port']
1164
1116
  print(username, password, host, port)
1165
1117
 
1166
- ss = '2024-11-08'
1167
- ss= re.sub(r'\\N', '0', ss)
1168
- print(ss, '111')
1118
+ df = pd.read_excel('/Users/xigua/Downloads/66563857.xlsx')
1119
+ ss = MysqlUpload(username, password, host, port)
1120
+ res, data = ss.convert_df_dtypes(df=df)
1121
+ print(data)
1122
+ print(res)
@@ -150,8 +150,8 @@ class ReCheckMysql:
150
150
  move_insert=True, # 先删除,再插入
151
151
  df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
152
152
  drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
153
+ count=None,
153
154
  filename='', # 用来追踪处理进度
154
- service_database={'company': 'mysql'}, # 字典
155
155
  )
156
156
 
157
157
 
mdbq/req_post/req_tb.py CHANGED
@@ -611,8 +611,8 @@ def company_run(service_databases=[]):
611
611
  move_insert=False, # 先删除,再插入
612
612
  df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
613
613
  drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
614
+ count=None,
614
615
  filename=None, # 用来追踪处理进度
615
- service_database=dt, # 字典
616
616
  )
617
617
  now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S ")
618
618
  print(f'{now} {db_name} -> {table_name}: 已入库')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mdbq
3
- Version: 2.9.3
3
+ Version: 2.9.5
4
4
  Home-page: https://pypi.org/project/mdbq
5
5
  Author: xigua,
6
6
  Author-email: 2587125111@qq.com
@@ -1,11 +1,11 @@
1
1
  mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
2
2
  mdbq/__version__.py,sha256=y9Mp_8x0BCZSHsdLT_q5tX9wZwd5QgqrSIENLrb6vXA,62
3
3
  mdbq/aggregation/__init__.py,sha256=EeDqX2Aml6SPx8363J-v1lz0EcZtgwIBYyCJV6CcEDU,40
4
- mdbq/aggregation/aggregation.py,sha256=IVh9SFO1yp12qDBuEOWTi9SAytYktKBrsPJNPuDetSM,73254
4
+ mdbq/aggregation/aggregation.py,sha256=3d_sx-cFrW-c03D5Ry9jf144Ph3d0znIl3IHmnInsYA,73902
5
5
  mdbq/aggregation/df_types.py,sha256=U9i3q2eRPTDY8qAPTw7irzu-Tlg4CIySW9uYro81wdk,8125
6
6
  mdbq/aggregation/mysql_types.py,sha256=YTGyrF9vcRgfkQbpT-e-JdJ7c7VF1dDHgyx9YZRES8w,10934
7
7
  mdbq/aggregation/optimize_data.py,sha256=79uwiM2WqNNFxGpE2wKz742PRq-ZGgFjdOV0vgptHdY,3513
8
- mdbq/aggregation/query_data.py,sha256=zut8WyyAKTULfGWMltyQYqsVsIaBDUU8E3w2_UL4hbA,103248
8
+ mdbq/aggregation/query_data.py,sha256=0kiJQv7xLeH7kXxPmMiUUPYIlt5gcEyzSETmJTV372U,103891
9
9
  mdbq/bdup/__init__.py,sha256=AkhsGk81SkG1c8FqDH5tRq-8MZmFobVbN60DTyukYTY,28
10
10
  mdbq/bdup/bdup.py,sha256=LAV0TgnQpc-LB-YuJthxb0U42_VkPidzQzAagan46lU,4234
11
11
  mdbq/clean/__init__.py,sha256=A1d6x3L27j4NtLgiFV5TANwEkLuaDfPHDQNrPBbNWtU,41
@@ -13,12 +13,10 @@ mdbq/clean/clean_upload.py,sha256=yMAb6tV9XHhFJbRrCOeaPfszApJ9y5M4-hQGuBSXNqE,67
13
13
  mdbq/clean/data_clean.py,sha256=ucfslhqXVZoH2QaXHSAWDky0GhIvH9f4GeNaHg4SrFE,104790
14
14
  mdbq/company/__init__.py,sha256=qz8F_GsP_pMB5PblgJAUAMjasuZbOEp3qQOCB39E8f0,21
15
15
  mdbq/company/copysh.py,sha256=eFu6focRqm2Njn_XN1KW2ZYJiTv6EYgsdBCLokobyxQ,21572
16
- mdbq/company/copysh_bak.py,sha256=NvlXCBZBcO2GIT5nLRYYqhOyHWM1-1RE7DHvgbj6jmQ,19723
17
- mdbq/company/home_sh.py,sha256=42CZ2tZIXHLl2mOl2gk2fZnjH2IHh1VJ1s3qHABjonY,18021
18
16
  mdbq/config/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
19
17
  mdbq/config/get_myconf.py,sha256=cmNvsyoNa0RbZ9FOTjSd3jyyGwkxjUo0phvdHbGlrms,6010
20
18
  mdbq/config/myconfig.py,sha256=EGymTlAimtHIDJ9egCtOehBEPOj6rea504kvsEZu64o,854
21
- mdbq/config/products.py,sha256=Sj4FSb2dZcMKp6ox-FJdIR87QLgMN_TJ7Z6KAWMTWyw,6214
19
+ mdbq/config/products.py,sha256=StTRtphOmFccWxmb92lbIdQC6z83DpJVgYuVc4W7Rog,6296
22
20
  mdbq/config/set_support.py,sha256=xkZCX6y9Bq1ppBpJAofld4B2YtchA7fl0eT3dx3CrSI,777
23
21
  mdbq/config/update_conf.py,sha256=taL3ZqKgiVWwUrDFuaYhim9a72Hm4BHRhhDscJTziR8,4535
24
22
  mdbq/dataframe/__init__.py,sha256=2HtCN8AdRj53teXDqzysC1h8aPL-mMFy561ESmhehGQ,22
@@ -28,8 +26,8 @@ mdbq/log/mylogger.py,sha256=oaT7Bp-Hb9jZt52seP3ISUuxVcI19s4UiqTeouScBO0,3258
28
26
  mdbq/mongo/__init__.py,sha256=SILt7xMtQIQl_m-ik9WLtJSXIVf424iYgCfE_tnQFbw,13
29
27
  mdbq/mongo/mongo.py,sha256=v9qvrp6p1ZRWuPpbSilqveiE0FEcZF7U5xUPI0RN4xs,31880
30
28
  mdbq/mysql/__init__.py,sha256=A_DPJyAoEvTSFojiI2e94zP0FKtCkkwKP1kYUCSyQzo,11
31
- mdbq/mysql/mysql.py,sha256=tKkgjbOvy5uIn7Z-ws_biS-04-UHnr5rKqNvtWr_Yss,62024
32
- mdbq/mysql/recheck_mysql.py,sha256=jHQSlQy0PlQ_EYICQv_2nairUX3t6OIwPtSELKIpjkY,8702
29
+ mdbq/mysql/mysql.py,sha256=Ivw2Ke4-4_oTZb4naB_kh4jP24MJUUAhdGViNx8LA1E,59276
30
+ mdbq/mysql/recheck_mysql.py,sha256=rgTpvDMWYTyEn7UQdlig-pdXDluTgiU8JG6lkMh8DV0,8665
33
31
  mdbq/mysql/s_query.py,sha256=bgNNIqYLDCHjD5KTFcm6x4u74selpAGs5ouJYuqX86k,8447
34
32
  mdbq/mysql/year_month_day.py,sha256=VgewoE2pJxK7ErjfviL_SMTN77ki8GVbTUcao3vFUCE,1523
35
33
  mdbq/other/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
@@ -42,10 +40,10 @@ mdbq/pbix/pbix_refresh.py,sha256=JUjKW3bNEyoMVfVfo77UhguvS5AWkixvVhDbw4_MHco,239
42
40
  mdbq/pbix/refresh_all.py,sha256=OBT9EewSZ0aRS9vL_FflVn74d4l2G00wzHiikCC4TC0,5926
43
41
  mdbq/pbix/refresh_all_old.py,sha256=_pq3WSQ728GPtEG5pfsZI2uTJhU8D6ra-htIk1JXYzw,7192
44
42
  mdbq/req_post/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
45
- mdbq/req_post/req_tb.py,sha256=PexWSCPJNM6Tv0ol4lAWIhlOwsAr_frnjtcdSHCFiek,36179
43
+ mdbq/req_post/req_tb.py,sha256=qg7pet73IgKGmCwxaeUyImJIoeK_pBQT9BBKD7fkBNg,36160
46
44
  mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
47
45
  mdbq/spider/aikucun.py,sha256=jHrdGWBJQaSywx7V-U4YuM6vWkwC5SR5tTOOdB3YU_c,17306
48
- mdbq-2.9.3.dist-info/METADATA,sha256=fL1JR-lJNlMr2cIzQIEO460TetP9yzBerJPCJYnBRQ8,243
49
- mdbq-2.9.3.dist-info/WHEEL,sha256=cpQTJ5IWu9CdaPViMhC9YzF8gZuS5-vlfoFihTBC86A,91
50
- mdbq-2.9.3.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
51
- mdbq-2.9.3.dist-info/RECORD,,
46
+ mdbq-2.9.5.dist-info/METADATA,sha256=kXmviy083bUKwNHey1JZepeXQYgRTnz_ahy6pegjzJg,243
47
+ mdbq-2.9.5.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
48
+ mdbq-2.9.5.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
49
+ mdbq-2.9.5.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.1.0)
2
+ Generator: bdist_wheel (0.44.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5