mdbq 4.0.34__py3-none-any.whl → 4.0.35__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/__version__.py CHANGED
@@ -1 +1 @@
1
- VERSION = '4.0.34'
1
+ VERSION = '4.0.35'
@@ -4,6 +4,7 @@ from mdbq.mysql import uploader
4
4
  from mdbq.mysql import s_query
5
5
  from mdbq.myconf import myconf
6
6
  from mdbq.log import mylogger
7
+ from mdbq.other import error_handler
7
8
  import datetime
8
9
  from dateutil.relativedelta import relativedelta
9
10
  import pandas as pd
@@ -218,18 +219,7 @@ class MysqlDatasQuery:
218
219
  self.download_manager = download_manager
219
220
  self.pf_datas = []
220
221
 
221
- @staticmethod
222
- def try_except(func):
223
- @wraps(func)
224
- def wrapper(*args, **kwargs):
225
- try:
226
- return func(*args, **kwargs)
227
- except Exception as e:
228
- logger.info('函数执行错误', {'函数': func.__name__, '错误': str(e), 'args': args, 'kwargs': kwargs})
229
-
230
- return wrapper
231
-
232
- # @try_except
222
+ # @error_handler.log_on_exception(logger=logger)
233
223
  def tg_wxt(self, db_name='聚合数据', table_name='天猫_主体报表', is_maximize=True):
234
224
  start_date, end_date = self.months_data(num=self.months)
235
225
  projection = {
@@ -716,7 +706,7 @@ class MysqlDatasQuery:
716
706
  'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量', '自然流量曝光量']], # 唯一约束列表
717
707
  }
718
708
 
719
- @try_except
709
+ @error_handler.log_on_exception(logger=logger)
720
710
  @upload_data_decorator()
721
711
  def syj(self, db_name='聚合数据', table_name='生意经_宝贝指标'):
722
712
  start_date, end_date = self.months_data(num=self.months)
@@ -791,7 +781,7 @@ class MysqlDatasQuery:
791
781
  'unique_keys': [['日期', '店铺名称', '宝贝id']], # 唯一约束列表
792
782
  }
793
783
 
794
- @try_except
784
+ @error_handler.log_on_exception(logger=logger)
795
785
  @upload_data_decorator()
796
786
  def tg_rqbb(self, db_name='聚合数据', table_name='天猫_人群报表', is_maximize=True):
797
787
  start_date, end_date = self.months_data(num=self.months)
@@ -998,7 +988,7 @@ class MysqlDatasQuery:
998
988
  'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '人群名字']], # 唯一约束列表
999
989
  }
1000
990
 
1001
- @try_except
991
+ @error_handler.log_on_exception(logger=logger)
1002
992
  @upload_data_decorator()
1003
993
  def tg_gjc(self, db_name='聚合数据', table_name='天猫_关键词报表', is_maximize=True):
1004
994
  start_date, end_date = self.months_data(num=self.months)
@@ -1160,7 +1150,7 @@ class MysqlDatasQuery:
1160
1150
  return pd.DataFrame()
1161
1151
  return df
1162
1152
 
1163
- @try_except
1153
+ @error_handler.log_on_exception(logger=logger)
1164
1154
  @upload_data_decorator()
1165
1155
  def tg_cjzb(self, db_name='聚合数据', table_name='天猫_超级直播', is_maximize=True):
1166
1156
  start_date, end_date = self.months_data(num=self.months)
@@ -1297,7 +1287,7 @@ class MysqlDatasQuery:
1297
1287
  'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '人群名字', '计划名字']], # 唯一约束列表
1298
1288
  }
1299
1289
 
1300
- @try_except
1290
+ @error_handler.log_on_exception(logger=logger)
1301
1291
  def pxb_zh(self, db_name='聚合数据', table_name='天猫_品销宝账户报表', is_maximize=True):
1302
1292
  start_date, end_date = self.months_data(num=self.months)
1303
1293
  projection = {
@@ -1406,7 +1396,7 @@ class MysqlDatasQuery:
1406
1396
  'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '报表类型', '花费', '展现量']], # 唯一约束列表
1407
1397
  }
1408
1398
 
1409
- @try_except
1399
+ @error_handler.log_on_exception(logger=logger)
1410
1400
  def idbm(self, db_name='聚合数据', table_name='商品id编码表'):
1411
1401
  """ 用生意经日数据制作商品 id 和编码对照表 """
1412
1402
  projection = {
@@ -1455,7 +1445,7 @@ class MysqlDatasQuery:
1455
1445
  'unique_keys': [['宝贝id']], # 唯一约束列表
1456
1446
  }
1457
1447
 
1458
- @try_except
1448
+ @error_handler.log_on_exception(logger=logger)
1459
1449
  @upload_data_decorator()
1460
1450
  def sp_picture(self, db_name='聚合数据', table_name='商品id图片对照表'):
1461
1451
  """ """
@@ -1690,7 +1680,7 @@ class MysqlDatasQuery:
1690
1680
  'unique_keys': [['日期', '店铺名称', '商品id']], # 唯一约束列表
1691
1681
  }
1692
1682
 
1693
- # @try_except
1683
+ # @error_handler.log_on_exception(logger=logger)
1694
1684
  @upload_data_decorator()
1695
1685
  def dplyd(self, db_name='聚合数据', table_name='店铺流量来源构成'):
1696
1686
  """ 新旧版取的字段是一样的 """
@@ -1795,7 +1785,7 @@ class MysqlDatasQuery:
1795
1785
  'unique_keys': [['日期', '店铺名称', '类别', '来源构成', '一级来源', '二级来源', '三级来源']], # 唯一约束列表
1796
1786
  }
1797
1787
 
1798
- @try_except
1788
+ @error_handler.log_on_exception(logger=logger)
1799
1789
  @upload_data_decorator()
1800
1790
  def sp_cost(self, db_name='聚合数据', table_name='商品成本'):
1801
1791
  """ 电商定价 """
@@ -1832,7 +1822,7 @@ class MysqlDatasQuery:
1832
1822
  'unique_keys': [['款号']], # 唯一约束列表
1833
1823
  }
1834
1824
 
1835
- # @try_except
1825
+ # @error_handler.log_on_exception(logger=logger)
1836
1826
  @upload_data_decorator()
1837
1827
  def jdjzt(self, db_name='聚合数据', table_name='京东_京准通'):
1838
1828
  start_date, end_date = self.months_data(num=self.months)
@@ -1936,7 +1926,7 @@ class MysqlDatasQuery:
1936
1926
  'unique_keys': [['日期', '店铺名称', '产品线', '触发sku_id', '跟单sku_id', '花费']], # 唯一约束列表
1937
1927
  }
1938
1928
 
1939
- @try_except
1929
+ @error_handler.log_on_exception(logger=logger)
1940
1930
  @upload_data_decorator()
1941
1931
  def jdqzyx(self, db_name='聚合数据', table_name='京东_京准通_全站营销'):
1942
1932
  start_date, end_date = self.months_data(num=self.months)
@@ -2003,7 +1993,7 @@ class MysqlDatasQuery:
2003
1993
  'unique_keys': [['日期', '店铺名称', '产品线']], # 唯一约束列表
2004
1994
  }
2005
1995
 
2006
- @try_except
1996
+ @error_handler.log_on_exception(logger=logger)
2007
1997
  @upload_data_decorator()
2008
1998
  def jd_gjc(self, db_name='聚合数据', table_name='京东_关键词报表'):
2009
1999
  start_date, end_date = self.months_data(num=self.months)
@@ -2102,7 +2092,7 @@ class MysqlDatasQuery:
2102
2092
  'unique_keys': [['日期', '产品线', '计划id', '搜索词', '关键词']], # 唯一约束列表
2103
2093
  }
2104
2094
 
2105
- @try_except
2095
+ @error_handler.log_on_exception(logger=logger)
2106
2096
  @upload_data_decorator()
2107
2097
  def sku_sales(self, db_name='聚合数据', table_name='京东_sku_商品明细'):
2108
2098
  start_date, end_date = self.months_data(num=self.months)
@@ -2164,7 +2154,7 @@ class MysqlDatasQuery:
2164
2154
  'unique_keys': [['日期', '店铺名称', '商品id']], # 唯一约束列表
2165
2155
  }
2166
2156
 
2167
- @try_except
2157
+ @error_handler.log_on_exception(logger=logger)
2168
2158
  @upload_data_decorator()
2169
2159
  def spu_sales(self, db_name='聚合数据', table_name='京东_spu_商品明细'):
2170
2160
  start_date, end_date = self.months_data(num=self.months)
@@ -2235,7 +2225,7 @@ class MysqlDatasQuery:
2235
2225
  start_date = f'{start_date.year}-{start_date.month}-01' # 替换为 n 月以前的第一天
2236
2226
  return pd.to_datetime(start_date), pd.to_datetime(end_date)
2237
2227
 
2238
- @try_except
2228
+ @error_handler.log_on_exception(logger=logger)
2239
2229
  @upload_data_decorator()
2240
2230
  def se_search(self, db_name='聚合数据', table_name='天猫店铺来源_手淘搜索'):
2241
2231
  start_date, end_date = self.months_data(num=self.months)
@@ -2299,7 +2289,7 @@ class MysqlDatasQuery:
2299
2289
  'unique_keys': [['日期', '店铺名称', '词类型', '搜索词']], # 唯一约束列表
2300
2290
  }
2301
2291
 
2302
- @try_except
2292
+ @error_handler.log_on_exception(logger=logger)
2303
2293
  @upload_data_decorator()
2304
2294
  def zb_ccfx(self, db_name='聚合数据', table_name='生意参谋_直播场次分析'):
2305
2295
  start_date, end_date = self.months_data(num=self.months)
@@ -2437,7 +2427,7 @@ class MysqlDatasQuery:
2437
2427
  'unique_keys': [['场次id']], # 唯一约束列表
2438
2428
  }
2439
2429
 
2440
- # @try_except
2430
+ # @error_handler.log_on_exception(logger=logger)
2441
2431
  @upload_data_decorator()
2442
2432
  def tg_by_day(self, db_name='聚合数据', table_name='多店推广场景_按日聚合'):
2443
2433
  """
@@ -2896,7 +2886,7 @@ class MysqlDatasQuery:
2896
2886
  'unique_keys': [['日期', '店铺名称', '营销场景']], # 唯一约束列表
2897
2887
  }
2898
2888
 
2899
- @try_except
2889
+ @error_handler.log_on_exception(logger=logger)
2900
2890
  @upload_data_decorator()
2901
2891
  def aikucun_bd_spu(self, db_name='聚合数据', table_name='爱库存_商品spu榜单'):
2902
2892
  start_date, end_date = self.months_data(num=self.months)
@@ -3109,7 +3099,7 @@ class MysqlDatasQuery:
3109
3099
  'unique_keys': [['日期', '店铺名称', '场景id', '父渠道id']], # 唯一约束列表
3110
3100
  }
3111
3101
 
3112
- # @try_except
3102
+ # @error_handler.log_on_exception(logger=logger)
3113
3103
  @upload_data_decorator()
3114
3104
  def dmp_crowd(self, db_name='聚合数据', table_name='达摩盘_人群报表'):
3115
3105
  start_date, end_date = self.months_data(num=self.months)
@@ -3215,7 +3205,7 @@ class MysqlDatasQuery:
3215
3205
  'unique_keys': [['日期', '店铺名称', '人群id', '营销渠道', '计划基础信息', '推广单元信息']], # 唯一约束列表
3216
3206
  }
3217
3207
 
3218
- @try_except
3208
+ @error_handler.log_on_exception(logger=logger)
3219
3209
  def ret_keyword(self, keyword, as_file=False):
3220
3210
  """ 推广关键词报表,关键词分类, """
3221
3211
  datas = [
@@ -3379,7 +3369,7 @@ class MysqlDatasQuery:
3379
3369
  break
3380
3370
  return result
3381
3371
 
3382
- @try_except
3372
+ @error_handler.log_on_exception(logger=logger)
3383
3373
  def set_crowd(self, keyword, as_file=False):
3384
3374
  """ 推广人群报表,人群分类, """
3385
3375
  result_a = re.findall('_a$|_a_|_ai|^a_', str(keyword), re.IGNORECASE)
@@ -3413,7 +3403,7 @@ class MysqlDatasQuery:
3413
3403
  if not is_res:
3414
3404
  return ''
3415
3405
 
3416
- @try_except
3406
+ @error_handler.log_on_exception(logger=logger)
3417
3407
  def set_crowd2(self, keyword, as_file=False):
3418
3408
  """ 推广人群报表,人群分类, """
3419
3409
  datas = [
@@ -3508,7 +3498,7 @@ class MysqlDatasQuery:
3508
3498
  break
3509
3499
  return result
3510
3500
 
3511
- # @try_except
3501
+ # @error_handler.log_on_exception(logger=logger)
3512
3502
  @upload_data_decorator()
3513
3503
  def performance_concat(self, db_name, table_name, bb_tg=True):
3514
3504
  tg = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '天猫汇总表调用'][0]
mdbq/log/mylogger.py CHANGED
@@ -549,7 +549,7 @@ def main():
549
549
  sensitive_fields=[], # 敏感字段列表
550
550
  enable_metrics=False, # 是否启用性能指标
551
551
  )
552
- logger.info('123')
552
+ logger.info('123', extra={'extra_data': {'test': 'test'}})
553
553
  logger.shutdown()
554
554
 
555
555
 
@@ -0,0 +1,119 @@
1
+ import traceback
2
+ import sys
3
+ from functools import wraps
4
+ import inspect
5
+
6
+
7
+ def log_on_exception(logger=None):
8
+ def decorator(func):
9
+ @wraps(func)
10
+ def wrapper(*args, **kwargs):
11
+ try:
12
+ return func(*args, **kwargs)
13
+ except Exception as e:
14
+ stack_lines = traceback.format_exc().splitlines(keepends=True)
15
+ if len(stack_lines) > 40:
16
+ stack_summary = ''.join(stack_lines[:20]) + '\n...\n' + ''.join(stack_lines[-20:])
17
+ else:
18
+ stack_summary = ''.join(stack_lines)
19
+ error_info = {
20
+ '函数': func.__name__,
21
+ '模块': func.__module__,
22
+ '类型': type(e).__name__,
23
+ '消息': str(e),
24
+ '签名': str(inspect.signature(func)),
25
+ 'args': [str(arg) for arg in args] if args else [],
26
+ 'kwargs': {k: str(v) for k, v in kwargs.items()} if kwargs else {},
27
+ '函数文件': func.__code__.co_filename,
28
+ '函数行号': func.__code__.co_firstlineno,
29
+ '异常行号': traceback.extract_tb(sys.exc_info()[2])[-1].lineno if sys.exc_info()[2] else None,
30
+ '异常文件': traceback.extract_tb(sys.exc_info()[2])[-1].filename if sys.exc_info()[2] else None,
31
+ '堆栈': stack_summary,
32
+ }
33
+ if logger:
34
+ logger.error(f"执行失败", {'details': error_info})
35
+
36
+ # print(error_info)
37
+ # raise # 重新抛出异常
38
+
39
+ return None # 或者返回其他默认值
40
+
41
+ return wrapper
42
+ return decorator
43
+
44
+
45
+ def log_on_exception_with_retry(max_retries=3, delay=1, logger=None):
46
+ def decorator(func):
47
+ @wraps(func)
48
+ def wrapper(*args, **kwargs):
49
+ last_exception = None
50
+
51
+ for attempt in range(max_retries):
52
+ try:
53
+ return func(*args, **kwargs)
54
+ except Exception as e:
55
+ import time
56
+ last_exception = e
57
+ error_info = {
58
+ '函数': func.__name__,
59
+ '重试': attempt + 1,
60
+ '最大重试': max_retries,
61
+ '类型': type(e).__name__,
62
+ '消息': str(e),
63
+ }
64
+
65
+ if logger:
66
+ logger.warning(f"函数 {func.__name__} 第 {attempt + 1} 次尝试失败", {'details': error_info})
67
+
68
+ if attempt < max_retries - 1:
69
+ time.sleep(delay)
70
+ if logger:
71
+ logger.info(f"⏳ 第 {attempt + 1} 次尝试失败,{delay}秒后重试...")
72
+ else:
73
+ if logger:
74
+ logger.error(f"❌ 函数 {func.__name__} 在 {max_retries} 次尝试后仍然失败")
75
+
76
+ final_error_info = {
77
+ '函数': func.__name__,
78
+ '最终错误类型': type(last_exception).__name__,
79
+ '最终错误消息': str(last_exception),
80
+ '总尝试次数': max_retries,
81
+ '堆栈跟踪': traceback.format_exc(),
82
+ }
83
+
84
+ if logger:
85
+ logger.error(f"函数 {func.__name__} 最终执行失败", {'details': final_error_info})
86
+
87
+ return None
88
+
89
+ return wrapper
90
+ return decorator
91
+
92
+
93
+ if __name__ == "__main__":
94
+ import logging
95
+ test_logger = logging.getLogger(__name__)
96
+ test_logger.setLevel(logging.INFO)
97
+
98
+ @log_on_exception(logger=test_logger)
99
+ def divide_numbers(a, b):
100
+ """测试函数:除法运算"""
101
+ return a / b
102
+
103
+ @log_on_exception_with_retry(max_retries=2, delay=0.5, logger=test_logger)
104
+ def fetch_data(url):
105
+ import random
106
+ """测试函数:模拟数据获取"""
107
+ if random.random() < 0.7: # 70% 概率失败
108
+ raise ConnectionError("网络连接失败")
109
+ return "数据获取成功"
110
+
111
+ # 测试基本错误处理
112
+ print("=== 测试基本错误处理 ===")
113
+ result1 = divide_numbers(10, 0)
114
+ result2 = divide_numbers(10, 2)
115
+ print(f"结果: {result2}")
116
+
117
+ print("\n=== 测试重试机制 ===")
118
+ result3 = fetch_data("http://example.com")
119
+ print(f"最终结果: {result3}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mdbq
3
- Version: 4.0.34
3
+ Version: 4.0.35
4
4
  Home-page: https://pypi.org/project/mdbq
5
5
  Author: xigua,
6
6
  Author-email: 2587125111@qq.com
@@ -1,9 +1,9 @@
1
1
  mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
2
- mdbq/__version__.py,sha256=D_wa3H06nsA6Arfalq9RVMZHoFDp3ZG4xsE24b2Lu8E,18
2
+ mdbq/__version__.py,sha256=B_ZDOEojo89VxQM2P_TRRgrJ65zx2UcvpOaQkIohFPI,18
3
3
  mdbq/aggregation/__init__.py,sha256=EeDqX2Aml6SPx8363J-v1lz0EcZtgwIBYyCJV6CcEDU,40
4
- mdbq/aggregation/query_data.py,sha256=VICC4R0yNktmfWHItn7X0769DyRBa2hBXhJOTp3Zh2w,169282
4
+ mdbq/aggregation/query_data.py,sha256=WtTFMN78jn43Y-nBTPAXhAK56w3wDuv_cj4YtzzGbZk,169797
5
5
  mdbq/log/__init__.py,sha256=Mpbrav0s0ifLL7lVDAuePEi1hJKiSHhxcv1byBKDl5E,15
6
- mdbq/log/mylogger.py,sha256=9w_o5mYB3FooIxobq_lSa6oCYTKIhPxDFox-jeLtUHI,21714
6
+ mdbq/log/mylogger.py,sha256=uC_KHsoCkxKKMVZTKYhe06Y5g6nUYuQYSEmK7YHLtlc,21754
7
7
  mdbq/myconf/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
8
8
  mdbq/myconf/myconf.py,sha256=rHvQCnQRKhQ49AZBke-Z4v28hyOLmHt4MylIuB0H6yA,33516
9
9
  mdbq/mysql/__init__.py,sha256=A_DPJyAoEvTSFojiI2e94zP0FKtCkkwKP1kYUCSyQzo,11
@@ -14,6 +14,7 @@ mdbq/mysql/unique_.py,sha256=MaztT-WIyEQUs-OOYY4pFulgHVcXR1BfCy3QUz0XM_U,21127
14
14
  mdbq/mysql/uploader.py,sha256=SVlrLxoYBEpTu_I771wAehJQVFWOCqXp-lNk2JNYFOE,81881
15
15
  mdbq/other/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
16
16
  mdbq/other/download_sku_picture.py,sha256=X66sVdvVgzoNzmgVJyPtd7bjEvctEKtLPblEPF65EWc,46940
17
+ mdbq/other/error_handler.py,sha256=ZeuvQM4qRYGA1a9gCijwYZ-NbA4coijMkbC2tqTNBU0,4590
17
18
  mdbq/other/otk.py,sha256=iclBIFbQbhlqzUbcMMoePXBpcP1eZ06ZtjnhcA_EbmE,7241
18
19
  mdbq/other/pov_city.py,sha256=AEOmCOzOwyjHi9LLZWPKi6DUuSC-_M163664I52u9qw,21050
19
20
  mdbq/other/ua_sj.py,sha256=JuVYzc_5QZ9s_oQSrTHVKkQv4S_7-CWx4oIKOARn_9U,22178
@@ -24,7 +25,7 @@ mdbq/redis/__init__.py,sha256=YtgBlVSMDphtpwYX248wGge1x-Ex_mMufz4-8W0XRmA,12
24
25
  mdbq/redis/getredis.py,sha256=vpBuNc22uj9Vr-_Dh25_wpwWM1e-072EAAIBdB_IpL0,23494
25
26
  mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
26
27
  mdbq/spider/aikucun.py,sha256=XptHjGzbout9IYzWAOQUpMMV5qEgLTU8pL1ZGt8oNEA,21868
27
- mdbq-4.0.34.dist-info/METADATA,sha256=m5KXyEfQlxynSXm8ht6Owk0UZ-zi8MOo2AKy9lmYODg,364
28
- mdbq-4.0.34.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
29
- mdbq-4.0.34.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
30
- mdbq-4.0.34.dist-info/RECORD,,
28
+ mdbq-4.0.35.dist-info/METADATA,sha256=okq1WCntJO--DHv5eIqIAwDggX6rHeFRfIR2xZQqnGs,364
29
+ mdbq-4.0.35.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
30
+ mdbq-4.0.35.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
31
+ mdbq-4.0.35.dist-info/RECORD,,
File without changes