mdbq 4.0.1__py3-none-any.whl → 4.0.3__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.
@@ -1,6 +1,7 @@
1
1
  # -*- coding: UTF-8 –*-
2
2
  import re
3
- from mdbq.mysql import mysql
3
+ # from mdbq.mysql import mysql
4
+ from mdbq.mysql import uploader
4
5
  from mdbq.mysql import s_query
5
6
  from mdbq.config import config
6
7
  from mdbq.log import mylogger
@@ -15,15 +16,12 @@ import time
15
16
  import calendar
16
17
  import concurrent.futures
17
18
 
18
- """
19
-
20
- """
21
-
22
19
  dir_path = os.path.expanduser("~")
23
20
  config_file = os.path.join(dir_path, 'spd.txt')
24
21
  content = config.read_config(file_path=config_file)
25
22
  username, password, host, port = content['username'], content['password'], content['host'], content['port']
26
- m_engine = mysql.MysqlUpload(username=username, password=password, host=host, port=port, charset='utf8mb4')
23
+ host = 'localhost'
24
+ uld = uploader.MySQLUploader(username=username, password=password, host=host, port=int(port), pool_size=10)
27
25
 
28
26
  logger = mylogger.MyLogger(
29
27
  logging_mode='file',
@@ -38,15 +36,103 @@ logger = mylogger.MyLogger(
38
36
  )
39
37
 
40
38
 
39
+ def upload_data_decorator(**upload_kwargs):
40
+ """
41
+ 数据上传装饰器
42
+ :param upload_kwargs: 上传参数,支持所有 upload_data 方法的参数
43
+ :return: 装饰器函数
44
+ """
45
+ def decorator(func):
46
+ @wraps(func)
47
+ def wrapper(*args, **kwargs):
48
+ try:
49
+ # 执行原始函数
50
+ result = func(*args, **kwargs)
51
+
52
+ # 如果返回 None,直接返回
53
+ if result is None:
54
+ return None
55
+
56
+ # 如果返回的是 DataFrame
57
+ if isinstance(result, pd.DataFrame):
58
+ # 设置默认值
59
+ default_kwargs = {
60
+ 'check_duplicate': False,
61
+ 'update_on_duplicate': True,
62
+ 'allow_null': False,
63
+ 'transaction_mode': 'batch'
64
+ }
65
+ # 更新参数,优先使用装饰器参数
66
+ merged_kwargs = {**default_kwargs, **upload_kwargs}
67
+
68
+ # 上传数据
69
+ uld.upload_data(
70
+ data=result,
71
+ **merged_kwargs
72
+ )
73
+ return True
74
+
75
+ # 如果返回的是元组
76
+ elif isinstance(result, tuple):
77
+ # 检查元组长度
78
+ if len(result) < 2:
79
+ logger.warning('函数返回的元组长度小于2,直接返回原结果,不执行上传', {'函数': func.__name__})
80
+ return result
81
+
82
+ # 获取前两个元素
83
+ df, extra_kwargs = result[0], result[1]
84
+
85
+ # 检查第一个元素是否为DataFrame
86
+ if not isinstance(df, pd.DataFrame):
87
+ logger.warning('函数返回的元组第一个元素不是DataFrame,直接返回原结果,不执行上传', {'函数': func.__name__})
88
+ return result
89
+
90
+ # 合并装饰器参数和函数参数
91
+ merged_kwargs = {**upload_kwargs}
92
+ merged_kwargs.update(extra_kwargs)
93
+
94
+ # 设置默认值
95
+ default_kwargs = {
96
+ 'check_duplicate': False,
97
+ 'update_on_duplicate': True,
98
+ 'allow_null': False,
99
+ 'transaction_mode': 'batch'
100
+ }
101
+ # 更新参数,优先使用装饰器参数
102
+ for key, value in default_kwargs.items():
103
+ if key not in merged_kwargs:
104
+ merged_kwargs[key] = value
105
+
106
+ # 上传数据
107
+ uld.upload_data(
108
+ data=df,
109
+ **merged_kwargs
110
+ )
111
+
112
+ # 如果元组长度大于2,返回完整元组
113
+ if len(result) > 2:
114
+ return result
115
+ return True
116
+
117
+ # 其他情况直接返回结果
118
+ return result
119
+
120
+ except Exception as e:
121
+ logger.error('数据上传失败', {'函数': func.__name__, '错误': str(e)})
122
+ return False
123
+
124
+ return wrapper
125
+ return decorator
126
+
127
+
41
128
  class MysqlDatasQuery:
42
129
  """
43
130
  从数据库中下载数据
44
131
  """
45
- def __init__(self):
132
+ def __init__(self, download_manager):
46
133
  # target_service 从哪个服务器下载数据
47
134
  self.months = 0 # 下载几个月数据, 0 表示当月, 1 是上月 1 号至今
48
- # 实例化一个下载类
49
- self.download = s_query.QueryDatas(username=username, password=password, host=host, port=port)
135
+ self.download_manager = download_manager
50
136
  self.update_service = True # 调试时加,true: 将数据写入 mysql 服务器
51
137
  self.pf_datas = []
52
138
  self.pf_datas_jd = [] # 京东聚合销售表
@@ -58,7 +144,7 @@ class MysqlDatasQuery:
58
144
  try:
59
145
  return func(*args, **kwargs)
60
146
  except Exception as e:
61
- logger.info(f'函数: {func.__name__}, 报错信息: {e}') # 将异常信息返回
147
+ logger.info('函数执行错误', {'函数': func.__name__, '错误': str(e)}) # 将异常信息返回
62
148
 
63
149
  return wrapper
64
150
 
@@ -82,7 +168,7 @@ class MysqlDatasQuery:
82
168
  }
83
169
  __res = []
84
170
  for year in range(2024, datetime.datetime.today().year+1):
85
- df = self.download.data_to_df(
171
+ df = self.download_manager.data_to_df(
86
172
  db_name='推广数据2',
87
173
  table_name=f'主体报表_{year}',
88
174
  start_date=start_date,
@@ -91,6 +177,7 @@ class MysqlDatasQuery:
91
177
  )
92
178
  __res.append(df)
93
179
  df = pd.concat(__res, ignore_index=True)
180
+
94
181
  df.rename(columns={
95
182
  '场景名字': '营销场景',
96
183
  '主体id': '商品id',
@@ -98,6 +185,7 @@ class MysqlDatasQuery:
98
185
  '总成交笔数': '成交笔数',
99
186
  '总成交金额': '成交金额'
100
187
  }, inplace=True)
188
+
101
189
  df = df.astype({
102
190
  '商品id': str,
103
191
  '花费': 'float64',
@@ -152,12 +240,7 @@ class MysqlDatasQuery:
152
240
  '直接成交笔数': 'int',
153
241
  '直接成交金额': 'decimal(12,2)',
154
242
  }
155
- # self.pf_datas.append(
156
- # {
157
- # '集合名称': table_name,
158
- # '数据主体': df[['日期', '店铺名称', '商品id', '花费', '成交金额', '直接成交金额']]
159
- # }
160
- # ) # 制作其他聚合表
243
+
161
244
  self.pf_datas.append(
162
245
  {
163
246
  '集合名称': '天猫汇总表调用',
@@ -166,21 +249,22 @@ class MysqlDatasQuery:
166
249
  '成交笔数', '成交金额', '直接成交笔数', '直接成交金额', '自然流量曝光量']]
167
250
  }
168
251
  ) # 制作其他聚合表
169
- if not self.update_service:
170
- return
171
- min_date = df['日期'].min()
172
- max_date = df['日期'].max()
173
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
174
- m_engine.df_to_mysql(
175
- df=df,
252
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
253
+ uld.upload_data(
176
254
  db_name=db_name,
177
255
  table_name=table_name,
178
- # icm_update=['日期', '推广渠道', '营销场景', '商品id', '花费'], # 增量更新, 在聚合数据中使用,其他不要用
179
- move_insert=True, # 先删除,再插入
180
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
181
- count=None,
182
- filename=None, # 用来追踪处理进度
183
- set_typ=set_typ,
256
+ data=df,
257
+ set_typ=set_typ, # 定义列和数据类型
258
+ primary_keys=[], # 创建唯一主键
259
+ check_duplicate=False, # 检查重复数据
260
+ duplicate_columns=[], # 指定排重的组合键
261
+ update_on_duplicate=True, # 更新旧数据
262
+ allow_null=False, # 允许插入空值
263
+ partition_by=None, # 分表方式
264
+ partition_date_column='日期', # 用于分表的日期列名,默认为'日期'
265
+ indexes=[], # 普通索引列
266
+ transaction_mode='batch', # 事务模式
267
+ unique_keys=[['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量', '自然流量曝光量']], # 唯一约束列表
184
268
  )
185
269
 
186
270
  # df_pic:商品排序索引表, 给 powerbi 中的主推款排序用的,(从上月1号到今天的总花费进行排序)
@@ -215,20 +299,26 @@ class MysqlDatasQuery:
215
299
  '花费': 'decimal(12,2)',
216
300
  '更新时间': 'timestamp',
217
301
  }
218
- logger.info(f'正在更新: mysql ({host}:{port}) 属性设置3/商品索引表_主推排序调用')
219
- m_engine.df_to_mysql(
220
- df=df_pic,
302
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': '属性设置3', '表': '商品索引表_主推排序调用'})
303
+ uld.upload_data(
221
304
  db_name='属性设置3',
222
305
  table_name='商品索引表_主推排序调用',
223
- icm_update=['商品id'], # 增量更新, 在聚合数据中使用,其他不要用
224
- move_insert=False, # 先删除,再插入
225
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
226
- count=None,
227
- filename=None, # 用来追踪处理进度
228
- set_typ=set_typ,
306
+ data=df_pic,
307
+ set_typ=set_typ, # 定义列和数据类型
308
+ primary_keys=[], # 创建唯一主键
309
+ check_duplicate=False, # 检查重复数据
310
+ duplicate_columns=[], # 指定排重的组合键
311
+ update_on_duplicate=True, # 更新旧数据
312
+ allow_null=False, # 允许插入空值
313
+ partition_by=None, # 分表方式
314
+ partition_date_column='日期', # 用于分表的日期列名,默认为'日期'
315
+ indexes=[], # 普通索引列
316
+ transaction_mode='batch', # 事务模式
317
+ unique_keys=[['商品id']], # 唯一约束列表
229
318
  )
230
319
  return True
231
320
 
321
+ @upload_data_decorator()
232
322
  def _tb_wxt(self, db_name='聚合数据', table_name='淘宝_主体报表', is_maximize=True):
233
323
  start_date, end_date = self.months_data(num=self.months)
234
324
  projection = {
@@ -248,7 +338,7 @@ class MysqlDatasQuery:
248
338
  }
249
339
  __res = []
250
340
  for year in range(2024, datetime.datetime.today().year+1):
251
- df = self.download.data_to_df(
341
+ df = self.download_manager.data_to_df(
252
342
  db_name='推广数据_淘宝店',
253
343
  table_name=f'主体报表_{year}',
254
344
  start_date=start_date,
@@ -318,25 +408,24 @@ class MysqlDatasQuery:
318
408
  '直接成交笔数': 'int',
319
409
  '直接成交金额': 'decimal(12,2)',
320
410
  }
411
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
412
+ return df, {
413
+ 'db_name': db_name,
414
+ 'table_name': table_name,
415
+ 'set_typ': set_typ,
416
+ 'primary_keys': [], # 创建唯一主键
417
+ 'check_duplicate': False, # 检查重复数据
418
+ 'duplicate_columns': [], # 指定排重的组合键
419
+ 'update_on_duplicate': True, # 更新旧数据
420
+ 'allow_null': False, # 允许插入空值
421
+ 'partition_by': None, # 分表方式
422
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
423
+ 'indexes': [], # 普通索引列
424
+ 'transaction_mode': 'batch', # 事务模式
425
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量', '自然流量曝光量']], # 唯一约束列表
426
+ }
321
427
 
322
- if not self.update_service:
323
- return
324
- min_date = df['日期'].min()
325
- max_date = df['日期'].max()
326
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
327
- m_engine.df_to_mysql(
328
- df=df,
329
- db_name=db_name,
330
- table_name=table_name,
331
- # icm_update=['日期', '推广渠道', '营销场景', '商品id', '花费'], # 增量更新, 在聚合数据中使用,其他不要用
332
- move_insert=True, # 先删除,再插入
333
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
334
- count=None,
335
- filename=None, # 用来追踪处理进度
336
- set_typ=set_typ,
337
- )
338
- return True
339
-
428
+ @upload_data_decorator()
340
429
  def _ald_wxt(self, db_name='聚合数据', table_name='奥莱店_主体报表', is_maximize=True):
341
430
  start_date, end_date = self.months_data(num=self.months)
342
431
  projection = {
@@ -356,7 +445,7 @@ class MysqlDatasQuery:
356
445
  }
357
446
  __res = []
358
447
  for year in range(2024, datetime.datetime.today().year+1):
359
- df = self.download.data_to_df(
448
+ df = self.download_manager.data_to_df(
360
449
  db_name='推广数据_奥莱店',
361
450
  table_name=f'主体报表_{year}',
362
451
  start_date=start_date,
@@ -426,25 +515,24 @@ class MysqlDatasQuery:
426
515
  '直接成交笔数': 'int',
427
516
  '直接成交金额': 'decimal(12,2)',
428
517
  }
518
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
519
+ return df, {
520
+ 'db_name': db_name,
521
+ 'table_name': table_name,
522
+ 'set_typ': set_typ,
523
+ 'primary_keys': [], # 创建唯一主键
524
+ 'check_duplicate': False, # 检查重复数据
525
+ 'duplicate_columns': [], # 指定排重的组合键
526
+ 'update_on_duplicate': True, # 更新旧数据
527
+ 'allow_null': False, # 允许插入空值
528
+ 'partition_by': None, # 分表方式
529
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
530
+ 'indexes': [], # 普通索引列
531
+ 'transaction_mode': 'batch', # 事务模式
532
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量', '自然流量曝光量']], # 唯一约束列表
533
+ }
429
534
 
430
- if not self.update_service:
431
- return
432
- min_date = df['日期'].min()
433
- max_date = df['日期'].max()
434
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
435
- m_engine.df_to_mysql(
436
- df=df,
437
- db_name=db_name,
438
- table_name=table_name,
439
- # icm_update=['日期', '推广渠道', '营销场景', '商品id', '花费'], # 增量更新, 在聚合数据中使用,其他不要用
440
- move_insert=True, # 先删除,再插入
441
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
442
- count=None,
443
- filename=None, # 用来追踪处理进度
444
- set_typ=set_typ,
445
- )
446
- return True
447
-
535
+ @upload_data_decorator()
448
536
  def _sj_wxt(self, db_name='聚合数据', table_name='圣积天猫店_主体报表', is_maximize=True):
449
537
  start_date, end_date = self.months_data(num=self.months)
450
538
  projection = {
@@ -464,7 +552,7 @@ class MysqlDatasQuery:
464
552
  }
465
553
  __res = []
466
554
  for year in range(2025, datetime.datetime.today().year+1):
467
- df = self.download.data_to_df(
555
+ df = self.download_manager.data_to_df(
468
556
  db_name='推广数据_圣积天猫店',
469
557
  table_name=f'主体报表_{year}',
470
558
  start_date=start_date,
@@ -534,26 +622,25 @@ class MysqlDatasQuery:
534
622
  '直接成交笔数': 'int',
535
623
  '直接成交金额': 'decimal(12,2)',
536
624
  }
537
-
538
- if not self.update_service:
539
- return
540
- min_date = df['日期'].min()
541
- max_date = df['日期'].max()
542
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
543
- m_engine.df_to_mysql(
544
- df=df,
545
- db_name=db_name,
546
- table_name=table_name,
547
- # icm_update=['日期', '推广渠道', '营销场景', '商品id', '花费'], # 增量更新, 在聚合数据中使用,其他不要用
548
- move_insert=True, # 先删除,再插入
549
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
550
- count=None,
551
- filename=None, # 用来追踪处理进度
552
- set_typ=set_typ,
553
- )
554
- return True
625
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
626
+ return df, {
627
+ 'db_name': db_name,
628
+ 'table_name': table_name,
629
+ 'set_typ': set_typ,
630
+ 'primary_keys': [], # 创建唯一主键
631
+ 'check_duplicate': False, # 检查重复数据
632
+ 'duplicate_columns': [], # 指定排重的组合键
633
+ 'update_on_duplicate': True, # 更新旧数据
634
+ 'allow_null': False, # 允许插入空值
635
+ 'partition_by': None, # 分表方式
636
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
637
+ 'indexes': [], # 普通索引列
638
+ 'transaction_mode': 'batch', # 事务模式
639
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量', '自然流量曝光量']], # 唯一约束列表
640
+ }
555
641
 
556
642
  @try_except
643
+ @upload_data_decorator()
557
644
  def syj(self, db_name='聚合数据', table_name='生意经_宝贝指标'):
558
645
  start_date, end_date = self.months_data(num=self.months)
559
646
  projection = {
@@ -573,7 +660,7 @@ class MysqlDatasQuery:
573
660
  }
574
661
  __res = []
575
662
  for year in range(2024, datetime.datetime.today().year + 1):
576
- df = self.download.data_to_df(
663
+ df = self.download_manager.data_to_df(
577
664
  db_name='生意经3',
578
665
  table_name=f'宝贝指标_{year}',
579
666
  start_date=start_date,
@@ -623,31 +710,25 @@ class MysqlDatasQuery:
623
710
  '件均价': 'mediumint',
624
711
  '价格带': 'varchar(100)',
625
712
  }
626
- # self.pf_datas.append(
627
- # {
628
- # '集合名称': table_name,
629
- # '数据主体': df[['日期', '店铺名称', '宝贝id', '销售额', '销售量', '退款额_发货后', '退货量_发货后']]
630
- # }
631
- # ) # 制作其他聚合表
632
- if not self.update_service:
633
- return
634
- min_date = df['日期'].min()
635
- max_date = df['日期'].max()
636
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
637
- m_engine.df_to_mysql(
638
- df=df,
639
- db_name=db_name,
640
- table_name=table_name,
641
- # icm_update=['日期', '宝贝id'], # 增量更新, 在聚合数据中使用,其他不要用
642
- move_insert=True, # 先删除,再插入
643
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
644
- count=None,
645
- filename=None, # 用来追踪处理进度
646
- set_typ=set_typ,
647
- )
648
- return True
713
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
714
+ return df, {
715
+ 'db_name': db_name,
716
+ 'table_name': table_name,
717
+ 'set_typ': set_typ,
718
+ 'primary_keys': [], # 创建唯一主键
719
+ 'check_duplicate': False, # 检查重复数据
720
+ 'duplicate_columns': [], # 指定排重的组合键
721
+ 'update_on_duplicate': True, # 更新旧数据
722
+ 'allow_null': False, # 允许插入空值
723
+ 'partition_by': None, # 分表方式
724
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
725
+ 'indexes': [], # 普通索引列
726
+ 'transaction_mode': 'batch', # 事务模式
727
+ 'unique_keys': [['日期', '店铺名称', '宝贝id']], # 唯一约束列表
728
+ }
649
729
 
650
730
  @try_except
731
+ @upload_data_decorator()
651
732
  def tg_rqbb(self, db_name='聚合数据', table_name='天猫_人群报表', is_maximize=True):
652
733
  start_date, end_date = self.months_data(num=self.months)
653
734
  projection = {
@@ -667,7 +748,7 @@ class MysqlDatasQuery:
667
748
  }
668
749
  __res = []
669
750
  for year in range(2024, datetime.datetime.today().year + 1):
670
- df = self.download.data_to_df(
751
+ df = self.download_manager.data_to_df(
671
752
  db_name='推广数据2',
672
753
  table_name=f'人群报表_{year}',
673
754
  start_date=start_date,
@@ -722,7 +803,7 @@ class MysqlDatasQuery:
722
803
  df.insert(loc=1, column='推广渠道', value='万相台无界版') # df中插入新列
723
804
 
724
805
  # 开始处理用户特征
725
- df_sx = self.download.data_to_df(
806
+ df_sx = self.download_manager.data_to_df(
726
807
  db_name='达摩盘3',
727
808
  table_name=f'我的人群属性',
728
809
  start_date=start_date,
@@ -847,23 +928,25 @@ class MysqlDatasQuery:
847
928
  '用户年龄': 'varchar(100)',
848
929
  '人群分类': 'varchar(100)',
849
930
  }
850
- min_date = df['日期'].min()
851
- max_date = df['日期'].max()
852
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
853
- m_engine.df_to_mysql(
854
- df=df,
855
- db_name=db_name,
856
- table_name=table_name,
857
- # icm_update=['日期', '推广渠道', '营销场景', '商品id', '花费', '人群名字'], # 增量更新, 在聚合数据中使用,其他不要用
858
- move_insert=True, # 先删除,再插入
859
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
860
- count=None,
861
- filename=None, # 用来追踪处理进度
862
- set_typ=set_typ,
863
- )
864
- return True
931
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
932
+ return df, {
933
+ 'db_name': db_name,
934
+ 'table_name': table_name,
935
+ 'set_typ': set_typ,
936
+ 'primary_keys': [], # 创建唯一主键
937
+ 'check_duplicate': False, # 检查重复数据
938
+ 'duplicate_columns': [], # 指定排重的组合键
939
+ 'update_on_duplicate': True, # 更新旧数据
940
+ 'allow_null': False, # 允许插入空值
941
+ 'partition_by': None, # 分表方式
942
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
943
+ 'indexes': [], # 普通索引列
944
+ 'transaction_mode': 'batch', # 事务模式
945
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '人群名字']], # 唯一约束列表
946
+ }
865
947
 
866
948
  @try_except
949
+ @upload_data_decorator()
867
950
  def tg_gjc(self, db_name='聚合数据', table_name='天猫_关键词报表', is_maximize=True):
868
951
  start_date, end_date = self.months_data(num=self.months)
869
952
  projection = {
@@ -884,7 +967,7 @@ class MysqlDatasQuery:
884
967
  }
885
968
  __res = []
886
969
  for year in range(2024, datetime.datetime.today().year + 1):
887
- df = self.download.data_to_df(
970
+ df = self.download_manager.data_to_df(
888
971
  db_name='推广数据2',
889
972
  table_name=f'关键词报表_{year}',
890
973
  start_date=start_date,
@@ -980,21 +1063,22 @@ class MysqlDatasQuery:
980
1063
  '是否品牌词': 'varchar(100)',
981
1064
  '词分类': 'varchar(100)',
982
1065
  }
983
- min_date = df['日期'].min()
984
- max_date = df['日期'].max()
985
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
986
- m_engine.df_to_mysql(
987
- df=df,
988
- db_name=db_name,
989
- table_name=table_name,
990
- # icm_update=['日期', '推广渠道', '营销场景', '商品id', '花费', '词类型', '词名字_词包名字',], # 增量更新, 在聚合数据中使用,其他不要用
991
- move_insert=True, # 先删除,再插入
992
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
993
- count=None,
994
- filename=None, # 用来追踪处理进度
995
- set_typ=set_typ,
996
- )
997
- return True
1066
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1067
+ return df, {
1068
+ 'db_name': db_name,
1069
+ 'table_name': table_name,
1070
+ 'set_typ': set_typ,
1071
+ 'primary_keys': [], # 创建唯一主键
1072
+ 'check_duplicate': False, # 检查重复数据
1073
+ 'duplicate_columns': [], # 指定排重的组合键
1074
+ 'update_on_duplicate': True, # 更新旧数据
1075
+ 'allow_null': False, # 允许插入空值
1076
+ 'partition_by': None, # 分表方式
1077
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1078
+ 'indexes': [], # 普通索引列
1079
+ 'transaction_mode': 'batch', # 事务模式
1080
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '词类型', '词名字_词包名字']], # 唯一约束列表
1081
+ }
998
1082
 
999
1083
  def tg_cjzb_qzt(self, projection=None, is_maximize=True):
1000
1084
  start_date, end_date = self.months_data(num=self.months)
@@ -1012,7 +1096,7 @@ class MysqlDatasQuery:
1012
1096
  }
1013
1097
  __res = []
1014
1098
  for year in range(2025, datetime.datetime.today().year + 1):
1015
- df = self.download.data_to_df(
1099
+ df = self.download_manager.data_to_df(
1016
1100
  db_name='推广数据2',
1017
1101
  table_name=f'超级直播_全站推广报表_{year}',
1018
1102
  start_date=start_date,
@@ -1027,6 +1111,7 @@ class MysqlDatasQuery:
1027
1111
 
1028
1112
 
1029
1113
  @try_except
1114
+ @upload_data_decorator()
1030
1115
  def tg_cjzb(self, db_name='聚合数据', table_name='天猫_超级直播', is_maximize=True):
1031
1116
  start_date, end_date = self.months_data(num=self.months)
1032
1117
  projection = {
@@ -1048,7 +1133,7 @@ class MysqlDatasQuery:
1048
1133
  }
1049
1134
  __res = []
1050
1135
  for year in range(2024, datetime.datetime.today().year + 1):
1051
- df = self.download.data_to_df(
1136
+ df = self.download_manager.data_to_df(
1052
1137
  db_name='推广数据2',
1053
1138
  table_name=f'超级直播报表_人群_{year}',
1054
1139
  start_date=start_date,
@@ -1129,8 +1214,6 @@ class MysqlDatasQuery:
1129
1214
  '数据主体': df[['日期', '店铺名称', '推广渠道', '营销场景', '花费', '展现量', '观看次数', '加购量', '成交笔数', '成交金额', '直接成交笔数', '直接成交金额']]
1130
1215
  },
1131
1216
  ) # 制作其他聚合表
1132
- if not self.update_service:
1133
- return
1134
1217
  set_typ = {
1135
1218
  '日期': 'date',
1136
1219
  '推广渠道': 'varchar(100)',
@@ -1149,22 +1232,23 @@ class MysqlDatasQuery:
1149
1232
  '直接成交笔数': 'int',
1150
1233
  '直接成交金额': 'decimal(12,2)',
1151
1234
  }
1152
- min_date = df['日期'].min()
1153
- max_date = df['日期'].max()
1154
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
1155
-
1156
- m_engine.df_to_mysql(
1157
- df=df,
1158
- db_name=db_name,
1159
- table_name=table_name,
1160
- # icm_update=['日期', '推广渠道', '营销场景', '花费'], # 增量更新, 在聚合数据中使用,其他不要用
1161
- move_insert=True, # 先删除,再插入
1162
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
1163
- count=None,
1164
- filename=None, # 用来追踪处理进度
1165
- set_typ=set_typ,
1166
- )
1167
- return True
1235
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1236
+
1237
+ return df, {
1238
+ 'db_name': db_name,
1239
+ 'table_name': table_name,
1240
+ 'set_typ': set_typ,
1241
+ 'primary_keys': [], # 创建唯一主键
1242
+ 'check_duplicate': False, # 检查重复数据
1243
+ 'duplicate_columns': [], # 指定排重的组合键
1244
+ 'update_on_duplicate': True, # 更新旧数据
1245
+ 'allow_null': False, # 允许插入空值
1246
+ 'partition_by': None, # 分表方式
1247
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1248
+ 'indexes': [], # 普通索引列
1249
+ 'transaction_mode': 'batch', # 事务模式
1250
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '人群名字', '计划名字']], # 唯一约束列表
1251
+ }
1168
1252
 
1169
1253
  @try_except
1170
1254
  def pxb_zh(self, db_name='聚合数据', table_name='天猫_品销宝账户报表', is_maximize=True):
@@ -1186,7 +1270,7 @@ class MysqlDatasQuery:
1186
1270
  }
1187
1271
  __res = []
1188
1272
  for year in range(2024, datetime.datetime.today().year + 1):
1189
- df = self.download.data_to_df(
1273
+ df = self.download_manager.data_to_df(
1190
1274
  db_name='推广数据2',
1191
1275
  table_name=f'品销宝_{year}',
1192
1276
  start_date=start_date,
@@ -1243,8 +1327,6 @@ class MysqlDatasQuery:
1243
1327
  '数据主体': df[['日期', '店铺名称', '推广渠道', '营销场景', '花费', '展现量', '点击量', '加购量', '成交笔数', '成交金额']]
1244
1328
  },
1245
1329
  ) # 制作其他聚合表
1246
- if not self.update_service:
1247
- return
1248
1330
  set_typ = {
1249
1331
  '日期': 'date',
1250
1332
  '推广渠道': 'varchar(100)',
@@ -1260,29 +1342,31 @@ class MysqlDatasQuery:
1260
1342
  '品牌搜索量': 'int',
1261
1343
  '品牌搜索人数': 'int',
1262
1344
  }
1263
- min_date = df['日期'].min()
1264
- max_date = df['日期'].max()
1265
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
1266
- m_engine.df_to_mysql(
1267
- df=df,
1268
- db_name=db_name,
1269
- table_name=table_name,
1270
- # icm_update=['日期', '报表类型', '推广渠道', '营销场景', '花费'], # 增量更新, 在聚合数据中使用,其他不要用
1271
- move_insert=True, # 先删除,再插入
1272
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
1273
- count=None,
1274
- filename=None, # 用来追踪处理进度
1275
- set_typ=set_typ,
1276
- )
1277
- return True
1345
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1346
+ return df, {
1347
+ 'db_name': db_name,
1348
+ 'table_name': table_name,
1349
+ 'set_typ': set_typ,
1350
+ 'primary_keys': [], # 创建唯一主键
1351
+ 'check_duplicate': False, # 检查重复数据
1352
+ 'duplicate_columns': [], # 指定排重的组合键
1353
+ 'update_on_duplicate': True, # 更新旧数据
1354
+ 'allow_null': False, # 允许插入空值
1355
+ 'partition_by': None, # 分表方式
1356
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1357
+ 'indexes': [], # 普通索引列
1358
+ 'transaction_mode': 'batch', # 事务模式
1359
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '报表类型']], # 唯一约束列表
1360
+ }
1278
1361
 
1279
1362
  @try_except
1363
+ @upload_data_decorator()
1280
1364
  def idbm_bak(self, db_name='聚合数据', table_name='商品id编码表'):
1281
1365
  """ 用生意经日数据制作商品 id 和编码对照表 """
1282
1366
  year = datetime.datetime.today().year
1283
1367
  data_values = []
1284
1368
  for year in range(2022, year+1):
1285
- data_values += self.download.columns_to_list(
1369
+ data_values += self.download_manager.columns_to_list(
1286
1370
  db_name='生意经3',
1287
1371
  table_name=f'宝贝指标_{year}',
1288
1372
  columns_name=['宝贝id', '商家编码', '行业类目'],
@@ -1308,27 +1392,22 @@ class MysqlDatasQuery:
1308
1392
  '二级类目': 'varchar(100)',
1309
1393
  '三级类目': 'varchar(100)',
1310
1394
  }
1311
- # self.pf_datas.append(
1312
- # {
1313
- # '集合名称': table_name,
1314
- # '数据主体': df[['宝贝id', '商家编码']]
1315
- # }
1316
- # ) # 制作其他聚合表
1317
- if not self.update_service:
1318
- return
1319
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name}')
1320
- m_engine.df_to_mysql(
1321
- df=df,
1322
- db_name=db_name,
1323
- table_name=table_name,
1324
- icm_update=['宝贝id'], # 增量更新, 在聚合数据中使用,其他不要用
1325
- move_insert=False, # 先删除,再插入
1326
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
1327
- count=None,
1328
- filename=None, # 用来追踪处理进度
1329
- set_typ=set_typ,
1330
- )
1331
- return True
1395
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1396
+ return df, {
1397
+ 'db_name': db_name,
1398
+ 'table_name': table_name,
1399
+ 'set_typ': set_typ,
1400
+ 'primary_keys': [], # 创建唯一主键
1401
+ 'check_duplicate': False, # 检查重复数据
1402
+ 'duplicate_columns': [], # 指定排重的组合键
1403
+ 'update_on_duplicate': True, # 更新旧数据
1404
+ 'allow_null': False, # 允许插入空值
1405
+ 'partition_by': None, # 分表方式
1406
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1407
+ 'indexes': [], # 普通索引列
1408
+ 'transaction_mode': 'batch', # 事务模式
1409
+ 'unique_keys': [['宝贝id']], # 唯一约束列表
1410
+ }
1332
1411
 
1333
1412
  @try_except
1334
1413
  def idbm(self, db_name='聚合数据', table_name='商品id编码表'):
@@ -1342,7 +1421,7 @@ class MysqlDatasQuery:
1342
1421
  '三级类目': 1,
1343
1422
  '更新时间': 1
1344
1423
  }
1345
- df = self.download.data_to_df(
1424
+ df = self.download_manager.data_to_df(
1346
1425
  db_name='属性设置3',
1347
1426
  table_name='商品sku属性',
1348
1427
  start_date='2024-11-17',
@@ -1362,83 +1441,25 @@ class MysqlDatasQuery:
1362
1441
  '三级类目': 'varchar(100)',
1363
1442
  '更新时间': 'timestamp'
1364
1443
  }
1365
- # self.pf_datas.append(
1366
- # {
1367
- # '集合名称': table_name,
1368
- # '数据主体': df[['宝贝id', '商家编码']]
1369
- # }
1370
- # ) # 制作其他聚合表
1371
- if not self.update_service:
1372
- return
1373
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name}')
1374
- m_engine.df_to_mysql(
1375
- df=df,
1376
- db_name=db_name,
1377
- table_name=table_name,
1378
- icm_update=['宝贝id'], # 增量更新, 在聚合数据中使用,其他不要用
1379
- move_insert=False, # 先删除,再插入
1380
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
1381
- count=None,
1382
- filename=None, # 用来追踪处理进度
1383
- set_typ=set_typ,
1384
- )
1385
- return True
1386
-
1387
- @try_except
1388
- def sp_picture_bak(self, db_name='聚合数据', table_name='商品id图片对照表'):
1389
- """ 用生意经日数据制作商品 id 和编码对照表 """
1390
- data_values = self.download.columns_to_list(
1391
- db_name='属性设置3',
1392
- table_name='商品素材中心',
1393
- columns_name=['日期', '商品id', '商品白底图', '方版场景图'],
1394
- )
1395
- df = pd.DataFrame(data=data_values)
1396
- df['商品id'] = df['商品id'].astype('int64')
1397
- df['日期'] = df['日期'].astype('datetime64[ns]')
1398
- df = df[(df['商品白底图'] != '0') | (df['方版场景图'] != '0')]
1399
- # 白底图优先
1400
- df['商品图片'] = df[['商品白底图', '方版场景图']].apply(
1401
- lambda x: x['商品白底图'] if x['商品白底图'] != '0' else x['方版场景图'], axis=1)
1402
- # # 方版场景图优先
1403
- # df['商品图片'] = df[['商品白底图', '方版场景图']].apply(
1404
- # lambda x: x['方版场景图'] if x['方版场景图'] != '0' else x['商品白底图'], axis=1)
1405
- df.sort_values(by=['商品id', '日期'], ascending=[False, True], ignore_index=True, inplace=True)
1406
- df.drop_duplicates(subset=['商品id'], keep='last', inplace=True, ignore_index=True)
1407
- df = df[['商品id', '商品图片', '日期']]
1408
- df['商品图片'] = df['商品图片'].apply(lambda x: x if 'http' in x else None) # 检查是否是 http 链接
1409
- df.dropna(how='all', subset=['商品图片'], axis=0, inplace=True) # 删除指定列含有空值的行
1410
- df['商品链接'] = df['商品id'].apply(
1411
- lambda x: f'https://detail.tmall.com/item.htm?id={str(x)}' if x and '.com' not in str(x) else x)
1412
- df.sort_values(by='商品id', ascending=False, ignore_index=True, inplace=True) # ascending=False 降序排列
1413
- set_typ = {
1414
- '商品id': 'bigint',
1415
- '商品图片': 'varchar(255)',
1416
- '日期': 'date',
1417
- '商品链接': 'varchar(255)',
1444
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1445
+ return df, {
1446
+ 'db_name': db_name,
1447
+ 'table_name': table_name,
1448
+ 'set_typ': set_typ,
1449
+ 'primary_keys': [], # 创建唯一主键
1450
+ 'check_duplicate': False, # 检查重复数据
1451
+ 'duplicate_columns': [], # 指定排重的组合键
1452
+ 'update_on_duplicate': True, # 更新旧数据
1453
+ 'allow_null': False, # 允许插入空值
1454
+ 'partition_by': None, # 分表方式
1455
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1456
+ 'indexes': [], # 普通索引列
1457
+ 'transaction_mode': 'batch', # 事务模式
1458
+ 'unique_keys': [['宝贝id']], # 唯一约束列表
1418
1459
  }
1419
- # self.pf_datas.append(
1420
- # {
1421
- # '集合名称': table_name,
1422
- # '数据主体': df[['商品id', '商品图片']]
1423
- # }
1424
- # ) # 制作其他聚合表
1425
- if not self.update_service:
1426
- return
1427
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name}')
1428
- m_engine.df_to_mysql(
1429
- df=df,
1430
- db_name=db_name,
1431
- table_name=table_name,
1432
- icm_update=['商品id'], # 增量更新, 在聚合数据中使用,其他不要用
1433
- move_insert=False, # 先删除,再插入
1434
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
1435
- count=None,
1436
- filename=None, # 用来追踪处理进度
1437
- set_typ=set_typ,
1438
- )
1439
- return True
1440
1460
 
1441
1461
  @try_except
1462
+ @upload_data_decorator()
1442
1463
  def sp_picture(self, db_name='聚合数据', table_name='商品id图片对照表'):
1443
1464
  """ """
1444
1465
  projection = {
@@ -1450,7 +1471,7 @@ class MysqlDatasQuery:
1450
1471
  'sku地址': 1,
1451
1472
  '更新时间': 1
1452
1473
  }
1453
- df = self.download.data_to_df(
1474
+ df = self.download_manager.data_to_df(
1454
1475
  db_name='属性设置3',
1455
1476
  table_name='商品sku属性',
1456
1477
  start_date='2024-11-17',
@@ -1471,40 +1492,35 @@ class MysqlDatasQuery:
1471
1492
  'sku地址': 'varchar(255)',
1472
1493
  '更新时间': 'timestamp'
1473
1494
  }
1474
- # # 制作其他聚合表
1475
- # self.pf_datas.append(
1476
- # {
1477
- # '集合名称': table_name,
1478
- # '数据主体': df[['商品id', '商品图片']]
1479
- # }
1480
- # )
1481
- if not self.update_service: # 调试加,是否继续执行下面的入库操作
1482
- return
1483
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name}')
1484
- m_engine.df_to_mysql(
1485
- df=df,
1486
- db_name=db_name,
1487
- table_name=table_name,
1488
- icm_update=['sku_id'], # 增量更新, 在聚合数据中使用,其他不要用
1489
- move_insert=False, # 先删除,再插入
1490
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
1491
- count=None,
1492
- filename=None, # 用来追踪处理进度
1493
- set_typ=set_typ,
1494
- )
1495
- return True
1495
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1496
+ return df, {
1497
+ 'db_name': db_name,
1498
+ 'table_name': table_name,
1499
+ 'set_typ': set_typ,
1500
+ 'primary_keys': [], # 创建唯一主键
1501
+ 'check_duplicate': False, # 检查重复数据
1502
+ 'duplicate_columns': [], # 指定排重的组合键
1503
+ 'update_on_duplicate': True, # 更新旧数据
1504
+ 'allow_null': False, # 允许插入空值
1505
+ 'partition_by': None, # 分表方式
1506
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1507
+ 'indexes': [], # 普通索引列
1508
+ 'transaction_mode': 'batch', # 事务模式
1509
+ 'unique_keys': [['sku_id']], # 唯一约束列表
1510
+ }
1496
1511
 
1512
+ @upload_data_decorator()
1497
1513
  def item_up(self, db_name='聚合数据', table_name='淘宝店铺货品'):
1498
1514
  start_date, end_date = self.months_data(num=self.months)
1499
1515
  projection = {}
1500
- df_set = self.download.data_to_df(
1516
+ df_set = self.download_manager.data_to_df(
1501
1517
  db_name='属性设置3',
1502
1518
  table_name=f'货品年份基准',
1503
1519
  start_date=start_date,
1504
1520
  end_date=end_date,
1505
1521
  projection={'商品id':1, '上市年份':1},
1506
1522
  )
1507
- df = self.download.data_to_df(
1523
+ df = self.download_manager.data_to_df(
1508
1524
  db_name='市场数据3',
1509
1525
  table_name=f'淘宝店铺数据',
1510
1526
  start_date=start_date,
@@ -1526,7 +1542,7 @@ class MysqlDatasQuery:
1526
1542
  df['上市年份'] = df['商品id'].apply(lambda x: check_year(x))
1527
1543
  p = df.pop('上市年份')
1528
1544
  df.insert(loc=5, column='上市年份', value=p)
1529
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name}')
1545
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1530
1546
  set_typ = {
1531
1547
  '日期': 'date',
1532
1548
  '店铺id': 'bigint',
@@ -1542,26 +1558,31 @@ class MysqlDatasQuery:
1542
1558
  '更新时间': 'timestamp',
1543
1559
  '上市年份': 'varchar(50)',
1544
1560
  }
1545
- m_engine.df_to_mysql(
1546
- df=df,
1547
- db_name=db_name,
1548
- table_name=table_name,
1549
- # icm_update=['日期', '一级来源', '二级来源', '三级来源', '访客数'], # 增量更新, 在聚合数据中使用,其他不要用
1550
- move_insert=True, # 先删除,再插入
1551
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
1552
- count=None,
1553
- filename=None, # 用来追踪处理进度
1554
- set_typ=set_typ,
1555
- )
1561
+ return df, {
1562
+ 'db_name': db_name,
1563
+ 'table_name': table_name,
1564
+ 'set_typ': set_typ,
1565
+ 'primary_keys': [], # 创建唯一主键
1566
+ 'check_duplicate': False, # 检查重复数据
1567
+ 'duplicate_columns': [], # 指定排重的组合键
1568
+ 'update_on_duplicate': True, # 更新旧数据
1569
+ 'allow_null': False, # 允许插入空值
1570
+ 'partition_by': None, # 分表方式
1571
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1572
+ 'indexes': [], # 普通索引列
1573
+ 'transaction_mode': 'batch', # 事务模式
1574
+ 'unique_keys': [['日期', '店铺id', '商品id']], # 唯一约束列表
1575
+ }
1556
1576
 
1557
1577
 
1578
+ @upload_data_decorator()
1558
1579
  def spph(self, db_name='聚合数据', table_name='天猫_商品排行'):
1559
1580
  """ """
1560
1581
  start_date, end_date = self.months_data(num=self.months)
1561
1582
  projection = {}
1562
1583
  __res = []
1563
1584
  for year in range(2024, datetime.datetime.today().year+1):
1564
- df = self.download.data_to_df(
1585
+ df = self.download_manager.data_to_df(
1565
1586
  db_name='生意参谋3',
1566
1587
  table_name=f'商品排行_{year}',
1567
1588
  start_date=start_date,
@@ -1572,7 +1593,7 @@ class MysqlDatasQuery:
1572
1593
  df = pd.concat(__res, ignore_index=True)
1573
1594
 
1574
1595
  projection = {}
1575
- df_set = self.download.data_to_df(
1596
+ df_set = self.download_manager.data_to_df(
1576
1597
  db_name='属性设置3',
1577
1598
  table_name=f'货品年份基准',
1578
1599
  start_date=start_date,
@@ -1663,22 +1684,25 @@ class MysqlDatasQuery:
1663
1684
  '更新时间': 'timestamp',
1664
1685
  '上市年份': 'varchar(100)',
1665
1686
  }
1666
- min_date = df['日期'].min().strftime("%Y-%m-%d")
1667
- max_date = df['日期'].max().strftime("%Y-%m-%d")
1668
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
1669
- m_engine.df_to_mysql(
1670
- df=df,
1671
- db_name=db_name,
1672
- table_name=table_name,
1673
- # icm_update=['日期', '一级来源', '二级来源', '三级来源', '访客数'], # 增量更新, 在聚合数据中使用,其他不要用
1674
- move_insert=True, # 先删除,再插入
1675
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
1676
- count=None,
1677
- filename=None, # 用来追踪处理进度
1678
- set_typ=set_typ,
1679
- )
1687
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1688
+ return df, {
1689
+ 'db_name': db_name,
1690
+ 'table_name': table_name,
1691
+ 'set_typ': set_typ,
1692
+ 'primary_keys': [], # 创建唯一主键
1693
+ 'check_duplicate': False, # 检查重复数据
1694
+ 'duplicate_columns': [], # 指定排重的组合键
1695
+ 'update_on_duplicate': True, # 更新旧数据
1696
+ 'allow_null': False, # 允许插入空值
1697
+ 'partition_by': None, # 分表方式
1698
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1699
+ 'indexes': [], # 普通索引列
1700
+ 'transaction_mode': 'batch', # 事务模式
1701
+ 'unique_keys': [['日期', '店铺名称', '商品id']], # 唯一约束列表
1702
+ }
1680
1703
 
1681
1704
  # @try_except
1705
+ @upload_data_decorator()
1682
1706
  def dplyd(self, db_name='聚合数据', table_name='店铺流量来源构成'):
1683
1707
  """ 新旧版取的字段是一样的 """
1684
1708
  start_date, end_date = self.months_data(num=self.months)
@@ -1701,7 +1725,7 @@ class MysqlDatasQuery:
1701
1725
  }
1702
1726
  __res = []
1703
1727
  for year in range(2024, datetime.datetime.today().year+1):
1704
- df = self.download.data_to_df(
1728
+ df = self.download_manager.data_to_df(
1705
1729
  db_name='生意参谋3',
1706
1730
  table_name=f'店铺流量来源构成_{year}',
1707
1731
  start_date=start_date,
@@ -1769,27 +1793,28 @@ class MysqlDatasQuery:
1769
1793
  '二级来源索引': 'smallint',
1770
1794
  '三级来源索引': 'smallint',
1771
1795
  }
1772
- # df.to_csv('/Users/xigua/Downloads/ll.csv', index=False, header=True, encoding='utf-8_sig')
1773
- min_date = df['日期'].min().strftime("%Y-%m-%d")
1774
- max_date = df['日期'].max().strftime("%Y-%m-%d")
1775
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
1776
- m_engine.df_to_mysql(
1777
- df=df,
1778
- db_name=db_name,
1779
- table_name=table_name,
1780
- # icm_update=['日期', '一级来源', '二级来源', '三级来源', '访客数'], # 增量更新, 在聚合数据中使用,其他不要用
1781
- move_insert=True, # 先删除,再插入
1782
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
1783
- count=None,
1784
- filename=None, # 用来追踪处理进度
1785
- set_typ=set_typ,
1786
- )
1787
- return True
1796
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '': table_name})
1797
+ return df, {
1798
+ 'db_name': db_name,
1799
+ 'table_name': table_name,
1800
+ 'set_typ': set_typ,
1801
+ 'primary_keys': [], # 创建唯一主键
1802
+ 'check_duplicate': False, # 检查重复数据
1803
+ 'duplicate_columns': [], # 指定排重的组合键
1804
+ 'update_on_duplicate': True, # 更新旧数据
1805
+ 'allow_null': False, # 允许插入空值
1806
+ 'partition_by': None, # 分表方式
1807
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1808
+ 'indexes': [], # 普通索引列
1809
+ 'transaction_mode': 'batch', # 事务模式
1810
+ 'unique_keys': [['日期', '店铺名称', '类别', '来源构成', '一级来源', '二级来源', '三级来源']], # 唯一约束列表
1811
+ }
1788
1812
 
1789
1813
  @try_except
1814
+ @upload_data_decorator()
1790
1815
  def sp_cost(self, db_name='聚合数据', table_name='商品成本'):
1791
1816
  """ 电商定价 """
1792
- data_values = self.download.columns_to_list(
1817
+ data_values = self.download_manager.columns_to_list(
1793
1818
  db_name='属性设置3',
1794
1819
  table_name='电商定价',
1795
1820
  columns_name=['日期', '款号', '年份季节', '吊牌价', '商家平台', '成本价', '天猫页面价', '天猫中促价'],
@@ -1806,31 +1831,25 @@ class MysqlDatasQuery:
1806
1831
  '天猫页面价': 'decimal(10,2)',
1807
1832
  '天猫中促价': 'decimal(10,2)',
1808
1833
  }
1809
- # self.pf_datas.append(
1810
- # {
1811
- # '集合名称': table_name,
1812
- # '数据主体': df[['款号', '成本价']]
1813
- # }
1814
- # ) # 制作其他聚合表
1815
- if not self.update_service:
1816
- return
1817
- min_date = pd.to_datetime(df['日期'].min()).strftime('%Y-%m-%d')
1818
- max_date = pd.to_datetime(df['日期'].max()).strftime('%Y-%m-%d')
1819
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
1820
- m_engine.df_to_mysql(
1821
- df=df,
1822
- db_name=db_name,
1823
- table_name=table_name,
1824
- icm_update=['款号'], # 增量更新, 在聚合数据中使用,其他不要用
1825
- move_insert=False, # 先删除,再插入
1826
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
1827
- count=None,
1828
- filename=None, # 用来追踪处理进度
1829
- set_typ=set_typ,
1830
- )
1831
- return True
1834
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1835
+ return df, {
1836
+ 'db_name': db_name,
1837
+ 'table_name': table_name,
1838
+ 'set_typ': set_typ,
1839
+ 'primary_keys': [], # 创建唯一主键
1840
+ 'check_duplicate': False, # 检查重复数据
1841
+ 'duplicate_columns': [], # 指定排重的组合键
1842
+ 'update_on_duplicate': True, # 更新旧数据
1843
+ 'allow_null': False, # 允许插入空值
1844
+ 'partition_by': None, # 分表方式
1845
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1846
+ 'indexes': [], # 普通索引列
1847
+ 'transaction_mode': 'batch', # 事务模式
1848
+ 'unique_keys': [['款号']], # 唯一约束列表
1849
+ }
1832
1850
 
1833
1851
  # @try_except
1852
+ @upload_data_decorator()
1834
1853
  def jdjzt(self, db_name='聚合数据', table_name='京东_京准通'):
1835
1854
  start_date, end_date = self.months_data(num=self.months)
1836
1855
  projection = {
@@ -1852,7 +1871,7 @@ class MysqlDatasQuery:
1852
1871
  }
1853
1872
  __res = []
1854
1873
  for year in range(2024, datetime.datetime.today().year + 1):
1855
- df = self.download.data_to_df(
1874
+ df = self.download_manager.data_to_df(
1856
1875
  db_name='京东数据3',
1857
1876
  table_name=f'推广数据_京准通_{year}',
1858
1877
  start_date=start_date,
@@ -1862,7 +1881,7 @@ class MysqlDatasQuery:
1862
1881
  __res.append(df)
1863
1882
  # 新增加自营店数据 2025-03-19
1864
1883
  for year in range(2025, datetime.datetime.today().year + 1):
1865
- df = self.download.data_to_df(
1884
+ df = self.download_manager.data_to_df(
1866
1885
  db_name='京东数据3',
1867
1886
  table_name=f'推广数据_京准通_自营店_{year}',
1868
1887
  start_date=start_date,
@@ -1889,7 +1908,7 @@ class MysqlDatasQuery:
1889
1908
  'sku_id': 1,
1890
1909
  'spu_id': 1,
1891
1910
  }
1892
- df_sku = self.download.data_to_df(
1911
+ df_sku = self.download_manager.data_to_df(
1893
1912
  db_name='属性设置3',
1894
1913
  table_name='京东商品属性',
1895
1914
  start_date=start_date,
@@ -1901,15 +1920,6 @@ class MysqlDatasQuery:
1901
1920
  df.pop('sku_id') # 删除聚合后合并进来的 sku id,实际使用 跟单sku_id
1902
1921
  p = df.pop('spu_id')
1903
1922
  df.insert(loc=3, column='spu_id', value=p)
1904
-
1905
- # self.pf_datas_jd.append(
1906
- # {
1907
- # '集合名称': table_name,
1908
- # '数据主体': df[['日期', '产品线', '触发sku_id', '跟单sku_id', '花费']]
1909
- # }
1910
- # ) # 制作其他聚合表
1911
- if not self.update_service:
1912
- return
1913
1923
  set_typ = {
1914
1924
  '日期': 'date',
1915
1925
  '店铺名称': 'varchar(100)',
@@ -1927,23 +1937,25 @@ class MysqlDatasQuery:
1927
1937
  '直接加购数': 'int',
1928
1938
  '总加购数': 'int',
1929
1939
  }
1930
- min_date = df['日期'].min()
1931
- max_date = df['日期'].max()
1932
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
1933
- m_engine.df_to_mysql(
1934
- df=df,
1935
- db_name=db_name,
1936
- table_name=table_name,
1937
- # icm_update=['日期', '产品线', '触发sku_id', '跟单sku_id', '花费', ], # 增量更新, 在聚合数据中使用,其他不要用
1938
- move_insert=True, # 先删除,再插入
1939
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
1940
- count=None,
1941
- filename=None, # 用来追踪处理进度
1942
- set_typ=set_typ,
1943
- )
1944
- return True
1940
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1941
+ return df, {
1942
+ 'db_name': db_name,
1943
+ 'table_name': table_name,
1944
+ 'set_typ': set_typ,
1945
+ 'primary_keys': [], # 创建唯一主键
1946
+ 'check_duplicate': False, # 检查重复数据
1947
+ 'duplicate_columns': [], # 指定排重的组合键
1948
+ 'update_on_duplicate': True, # 更新旧数据
1949
+ 'allow_null': False, # 允许插入空值
1950
+ 'partition_by': None, # 分表方式
1951
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1952
+ 'indexes': [], # 普通索引列
1953
+ 'transaction_mode': 'batch', # 事务模式
1954
+ 'unique_keys': [['日期', '店铺名称', '产品线', '触发sku_id', '跟单sku_id']], # 唯一约束列表
1955
+ }
1945
1956
 
1946
1957
  @try_except
1958
+ @upload_data_decorator()
1947
1959
  def jdqzyx(self, db_name='聚合数据', table_name='京东_京准通_全站营销'):
1948
1960
  start_date, end_date = self.months_data(num=self.months)
1949
1961
  projection = {
@@ -1959,7 +1971,7 @@ class MysqlDatasQuery:
1959
1971
  '核心位置展现量': 1,
1960
1972
  '核心位置点击量': 1,
1961
1973
  }
1962
- df = self.download.data_to_df(
1974
+ df = self.download_manager.data_to_df(
1963
1975
  db_name='京东数据3',
1964
1976
  table_name='推广数据_全站营销', # 暂缺
1965
1977
  start_date=start_date,
@@ -1967,7 +1979,7 @@ class MysqlDatasQuery:
1967
1979
  projection=projection,
1968
1980
  )
1969
1981
  if len(df) == 0:
1970
- return False
1982
+ return None, None
1971
1983
  df = df.groupby(['日期', '店铺名称', '产品线', '花费'], as_index=False).agg(
1972
1984
  **{
1973
1985
  '全站投产比': ('全站投产比', np.max),
@@ -1993,23 +2005,25 @@ class MysqlDatasQuery:
1993
2005
  '核心位置展现量': 'int',
1994
2006
  '核心位置点击量': 'int',
1995
2007
  }
1996
- min_date = df['日期'].min()
1997
- max_date = df['日期'].max()
1998
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
1999
- m_engine.df_to_mysql(
2000
- df=df,
2001
- db_name=db_name,
2002
- table_name=table_name,
2003
- # icm_update=['日期', '产品线', '花费'], # 增量更新, 在聚合数据中使用,其他不要用
2004
- move_insert=True, # 先删除,再插入
2005
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
2006
- count=None,
2007
- filename=None, # 用来追踪处理进度
2008
- set_typ=set_typ
2009
- )
2010
- return True
2008
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2009
+ return df, {
2010
+ 'db_name': db_name,
2011
+ 'table_name': table_name,
2012
+ 'set_typ': set_typ,
2013
+ 'primary_keys': [], # 创建唯一主键
2014
+ 'check_duplicate': False, # 检查重复数据
2015
+ 'duplicate_columns': [], # 指定排重的组合键
2016
+ 'update_on_duplicate': True, # 更新旧数据
2017
+ 'allow_null': False, # 允许插入空值
2018
+ 'partition_by': None, # 分表方式
2019
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
2020
+ 'indexes': [], # 普通索引列
2021
+ 'transaction_mode': 'batch', # 事务模式
2022
+ 'unique_keys': [['日期', '店铺名称', '产品线']], # 唯一约束列表
2023
+ }
2011
2024
 
2012
2025
  @try_except
2026
+ @upload_data_decorator()
2013
2027
  def jd_gjc(self, db_name='聚合数据', table_name='京东_关键词报表'):
2014
2028
  start_date, end_date = self.months_data(num=self.months)
2015
2029
  projection = {
@@ -2036,7 +2050,7 @@ class MysqlDatasQuery:
2036
2050
  }
2037
2051
  __res = []
2038
2052
  for year in range(2024, datetime.datetime.today().year + 1):
2039
- df = self.download.data_to_df(
2053
+ df = self.download_manager.data_to_df(
2040
2054
  db_name='京东数据3',
2041
2055
  table_name=f'推广数据_关键词报表_{year}',
2042
2056
  start_date=start_date,
@@ -2091,23 +2105,25 @@ class MysqlDatasQuery:
2091
2105
  'k_是否品牌词': 'varchar(100)',
2092
2106
  's_是否品牌词': 'varchar(100)',
2093
2107
  }
2094
- min_date = df['日期'].min()
2095
- max_date = df['日期'].max()
2096
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
2097
- m_engine.df_to_mysql(
2098
- df=df,
2099
- db_name=db_name,
2100
- table_name=table_name,
2101
- # icm_update=['日期', '产品线', '搜索词', '关键词', '展现数', '花费'], # 增量更新, 在聚合数据中使用,其他不要用
2102
- move_insert=True, # 先删除,再插入
2103
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
2104
- count=None,
2105
- filename=None, # 用来追踪处理进度
2106
- set_typ=set_typ
2107
- )
2108
- return True
2108
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2109
+ return df, {
2110
+ 'db_name': db_name,
2111
+ 'table_name': table_name,
2112
+ 'set_typ': set_typ,
2113
+ 'primary_keys': [], # 创建唯一主键
2114
+ 'check_duplicate': False, # 检查重复数据
2115
+ 'duplicate_columns': [], # 指定排重的组合键
2116
+ 'update_on_duplicate': True, # 更新旧数据
2117
+ 'allow_null': False, # 允许插入空值
2118
+ 'partition_by': None, # 分表方式
2119
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
2120
+ 'indexes': [], # 普通索引列
2121
+ 'transaction_mode': 'batch', # 事务模式
2122
+ 'unique_keys': [['日期', '产品线', '搜索词', '计划id', '搜索词', '关键词']], # 唯一约束列表
2123
+ }
2109
2124
 
2110
2125
  @try_except
2126
+ @upload_data_decorator()
2111
2127
  def sku_sales(self, db_name='聚合数据', table_name='京东_sku_商品明细'):
2112
2128
  start_date, end_date = self.months_data(num=self.months)
2113
2129
  projection = {
@@ -2125,7 +2141,7 @@ class MysqlDatasQuery:
2125
2141
  }
2126
2142
  __res = []
2127
2143
  for year in range(2024, datetime.datetime.today().year + 1):
2128
- df = self.download.data_to_df(
2144
+ df = self.download_manager.data_to_df(
2129
2145
  db_name='京东数据3',
2130
2146
  table_name=f'京东商智_sku_商品明细_{year}',
2131
2147
  start_date=start_date,
@@ -2146,14 +2162,6 @@ class MysqlDatasQuery:
2146
2162
  idx = df.groupby(['日期', '店铺名称', '商品id', '货号', '访客数', '成交客户数', '加购商品件数', '加购人数'])['更新时间'].idxmax()
2147
2163
  df = df.loc[idx]
2148
2164
  df = df[['日期', '店铺名称', '商品id', '货号', '访客数', '成交客户数', '加购商品件数', '加购人数', '成交单量', '成交金额']]
2149
- # self.pf_datas_jd.append(
2150
- # {
2151
- # '集合名称': table_name,
2152
- # '数据主体': df
2153
- # }
2154
- # ) # 制作其他聚合表
2155
- if not self.update_service:
2156
- return
2157
2165
  set_typ = {
2158
2166
  '日期': 'date',
2159
2167
  '店铺名称': 'varchar(100)',
@@ -2167,23 +2175,25 @@ class MysqlDatasQuery:
2167
2175
  '成交金额': 'decimal(10,2)',
2168
2176
  'sku_id': 'varchar(100)',
2169
2177
  }
2170
- min_date = df['日期'].min()
2171
- max_date = df['日期'].max()
2172
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
2173
- m_engine.df_to_mysql(
2174
- df=df,
2175
- db_name=db_name,
2176
- table_name=table_name,
2177
- # icm_update=['日期', '商品id', '成交单量'], # 增量更新, 在聚合数据中使用,其他不要用
2178
- move_insert=True, # 先删除,再插入
2179
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
2180
- count=None,
2181
- filename=None, # 用来追踪处理进度
2182
- set_typ=set_typ,
2183
- )
2184
- return True
2178
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2179
+ return df, {
2180
+ 'db_name': db_name,
2181
+ 'table_name': table_name,
2182
+ 'set_typ': set_typ,
2183
+ 'primary_keys': [], # 创建唯一主键
2184
+ 'check_duplicate': False, # 检查重复数据
2185
+ 'duplicate_columns': [], # 指定排重的组合键
2186
+ 'update_on_duplicate': True, # 更新旧数据
2187
+ 'allow_null': False, # 允许插入空值
2188
+ 'partition_by': None, # 分表方式
2189
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
2190
+ 'indexes': [], # 普通索引列
2191
+ 'transaction_mode': 'batch', # 事务模式
2192
+ 'unique_keys': [['日期', '店铺名称', '商品id']], # 唯一约束列表
2193
+ }
2185
2194
 
2186
2195
  @try_except
2196
+ @upload_data_decorator()
2187
2197
  def spu_sales(self, db_name='聚合数据', table_name='京东_spu_商品明细'):
2188
2198
  start_date, end_date = self.months_data(num=self.months)
2189
2199
  projection = {
@@ -2201,7 +2211,7 @@ class MysqlDatasQuery:
2201
2211
  }
2202
2212
  __res = []
2203
2213
  for year in range(2024, datetime.datetime.today().year + 1):
2204
- df = self.download.data_to_df(
2214
+ df = self.download_manager.data_to_df(
2205
2215
  db_name='京东数据3',
2206
2216
  table_name=f'京东商智_spu_商品明细_{year}',
2207
2217
  start_date=start_date,
@@ -2235,21 +2245,22 @@ class MysqlDatasQuery:
2235
2245
  '成交金额': 'decimal(10,2)',
2236
2246
  'spu_id': 'varchar(100)',
2237
2247
  }
2238
- min_date = df['日期'].min()
2239
- max_date = df['日期'].max()
2240
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
2241
- m_engine.df_to_mysql(
2242
- df=df,
2243
- db_name=db_name,
2244
- table_name=table_name,
2245
- # icm_update=['日期', '商品id', '成交单量'], # 增量更新, 在聚合数据中使用,其他不要用
2246
- move_insert=True, # 先删除,再插入
2247
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
2248
- count=None,
2249
- filename=None, # 用来追踪处理进度
2250
- set_typ=set_typ
2251
- )
2252
- return True
2248
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2249
+ return df, {
2250
+ 'db_name': db_name,
2251
+ 'table_name': table_name,
2252
+ 'set_typ': set_typ,
2253
+ 'primary_keys': [], # 创建唯一主键
2254
+ 'check_duplicate': False, # 检查重复数据
2255
+ 'duplicate_columns': [], # 指定排重的组合键
2256
+ 'update_on_duplicate': True, # 更新旧数据
2257
+ 'allow_null': False, # 允许插入空值
2258
+ 'partition_by': None, # 分表方式
2259
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
2260
+ 'indexes': [], # 普通索引列
2261
+ 'transaction_mode': 'batch', # 事务模式
2262
+ 'unique_keys': [['日期', '店铺名称', '商品id']], # 唯一约束列表
2263
+ }
2253
2264
 
2254
2265
  @staticmethod
2255
2266
  def months_data(num=0, end_date=None):
@@ -2261,6 +2272,7 @@ class MysqlDatasQuery:
2261
2272
  return pd.to_datetime(start_date), pd.to_datetime(end_date)
2262
2273
 
2263
2274
  @try_except
2275
+ @upload_data_decorator()
2264
2276
  def se_search(self, db_name='聚合数据', table_name='天猫店铺来源_手淘搜索'):
2265
2277
  start_date, end_date = self.months_data(num=self.months)
2266
2278
  projection = {
@@ -2281,7 +2293,7 @@ class MysqlDatasQuery:
2281
2293
  }
2282
2294
  __res = []
2283
2295
  for year in range(2024, datetime.datetime.today().year+1):
2284
- df = self.download.data_to_df(
2296
+ df = self.download_manager.data_to_df(
2285
2297
  db_name='生意参谋3',
2286
2298
  table_name=f'手淘搜索_本店引流词_{year}',
2287
2299
  start_date=start_date,
@@ -2290,19 +2302,6 @@ class MysqlDatasQuery:
2290
2302
  )
2291
2303
  __res.append(df)
2292
2304
  df = pd.concat(__res, ignore_index=True)
2293
- # df = df.groupby(
2294
- # ['日期', '店铺名称', '词类型', '搜索词'],
2295
- # as_index=False).agg(
2296
- # **{
2297
- # '访客数': ('访客数', np.max),
2298
- # '加购人数': ('加购人数', np.max),
2299
- # '支付金额': ('支付金额', np.max),
2300
- # '支付转化率': ('支付转化率', np.max),
2301
- # '支付买家数': ('支付买家数', np.max),
2302
- # '客单价': ('客单价', np.max),
2303
- # 'uv价值': ('uv价值', np.max)
2304
- # }
2305
- # )
2306
2305
  idx = df.groupby(['日期', '店铺名称', '词类型', '搜索词'])['更新时间'].idxmax()
2307
2306
  df = df.loc[idx]
2308
2307
  df = df[['日期', '店铺名称', '词类型', '搜索词', '访客数', '加购人数', '支付金额', '支付转化率', '支付买家数', '客单价', 'uv价值']]
@@ -2320,65 +2319,33 @@ class MysqlDatasQuery:
2320
2319
  '客单价': 'decimal(10,2)',
2321
2320
  'uv价值': 'decimal(10,2)',
2322
2321
  }
2323
- min_date = df['日期'].min()
2324
- max_date = df['日期'].max()
2325
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
2326
- m_engine.df_to_mysql(
2327
- df=df,
2328
- db_name=db_name,
2329
- table_name=table_name,
2330
- # icm_update=['日期', '店铺名称', '词类型', '搜索词'], # 增量更新, 在聚合数据中使用,其他不要用
2331
- move_insert=True, # 先删除,再插入
2332
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
2333
- count=None,
2334
- filename=None, # 用来追踪处理进度
2335
- set_typ=set_typ,
2336
- )
2337
- return True
2322
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2323
+ return df, {
2324
+ 'db_name': db_name,
2325
+ 'table_name': table_name,
2326
+ 'set_typ': set_typ,
2327
+ 'primary_keys': [], # 创建唯一主键
2328
+ 'check_duplicate': False, # 检查重复数据
2329
+ 'duplicate_columns': [], # 指定排重的组合键
2330
+ 'update_on_duplicate': True, # 更新旧数据
2331
+ 'allow_null': False, # 允许插入空值
2332
+ 'partition_by': None, # 分表方式
2333
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
2334
+ 'indexes': [], # 普通索引列
2335
+ 'transaction_mode': 'batch', # 事务模式
2336
+ 'unique_keys': [['日期', '店铺名称', '词类型', '搜索词']], # 唯一约束列表
2337
+ }
2338
2338
 
2339
2339
  @try_except
2340
+ @upload_data_decorator()
2340
2341
  def zb_ccfx(self, db_name='聚合数据', table_name='生意参谋_直播场次分析'):
2341
2342
  start_date, end_date = self.months_data(num=self.months)
2342
- projection = {
2343
- # '日期': 1,
2344
- # '店铺': 1,
2345
- # '场次信息': 1,
2346
- # '场次id': 1,
2347
- # '直播开播时间': 1,
2348
- # '开播时长': 1,
2349
- # '封面图点击率': 1,
2350
- # '观看人数': 1,
2351
- # '观看次数': 1,
2352
- # '新增粉丝数': 1,
2353
- # '流量券消耗': 1,
2354
- # '观看总时长(秒)': 1,
2355
- # '人均观看时长(秒)': 1,
2356
- # '次均观看时长(秒)': 1,
2357
- # '商品点击人数': 1,
2358
- # '商品点击次数': 1,
2359
- # '商品点击率': 1,
2360
- # '加购人数': 1,
2361
- # '加购件数': 1,
2362
- # '加购次数': 1,
2363
- # '成交金额(元)': 1,
2364
- # '成交人数': 1,
2365
- # '成交件数': 1,
2366
- # '成交笔数': 1,
2367
- # '成交转化率': 1,
2368
- # '退款人数': 1,
2369
- # '退款笔数': 1,
2370
- # '退款件数': 1,
2371
- # '退款金额': 1,
2372
- # '预售定金支付金额': 1,
2373
- # '预售预估总金额': 1,
2374
- # '店铺名称': 1,
2375
- }
2376
- df = self.download.data_to_df(
2343
+ df = self.download_manager.data_to_df(
2377
2344
  db_name='生意参谋3',
2378
2345
  table_name='直播分场次效果',
2379
2346
  start_date=start_date,
2380
2347
  end_date=end_date,
2381
- projection=projection,
2348
+ projection={},
2382
2349
  )
2383
2350
  df.drop_duplicates(subset=['场次id'], keep='first', inplace=True, ignore_index=True)
2384
2351
  set_typ = {
@@ -2455,9 +2422,7 @@ class MysqlDatasQuery:
2455
2422
  '封面图': 'text',
2456
2423
  '更新时间': 'timestamp',
2457
2424
  }
2458
- min_date = df['日期'].min()
2459
- max_date = df['日期'].max()
2460
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
2425
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2461
2426
  new_dict = {
2462
2427
  '日期': '',
2463
2428
  '店铺名称': '',
@@ -2496,16 +2461,26 @@ class MysqlDatasQuery:
2496
2461
  new_dict.update(dict_data)
2497
2462
  _results.append(new_dict)
2498
2463
  if _results:
2499
- m_engine.insert_many_dict(
2500
- db_name=db_name,
2501
- table_name=table_name,
2502
- dict_data_list=_results,
2503
- icm_update=['场次id'], # 唯一组合键
2504
- set_typ=set_typ, # 指定数据类型
2505
- )
2506
- return True
2464
+ return _results, {
2465
+ 'db_name': db_name,
2466
+ 'table_name': table_name,
2467
+ 'set_typ': set_typ,
2468
+ 'primary_keys': ['场次id'], # 创建唯一主键
2469
+ 'check_duplicate': False, # 检查重复数据
2470
+ 'duplicate_columns': [], # 指定排重的组合键
2471
+ 'update_on_duplicate': True, # 更新旧数据
2472
+ 'allow_null': False, # 允许插入空值
2473
+ 'partition_by': None, # 分表方式
2474
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
2475
+ 'indexes': [], # 普通索引列
2476
+ 'transaction_mode': 'batch', # 事务模式
2477
+ 'unique_keys': [['场次id']], # 唯一约束列表
2478
+ }
2479
+ else:
2480
+ return None, None
2507
2481
 
2508
2482
  # @try_except
2483
+ @upload_data_decorator()
2509
2484
  def tg_by_day(self, db_name='聚合数据', table_name='多店推广场景_按日聚合'):
2510
2485
  """
2511
2486
  汇总各个店铺的推广数据,按日汇总
@@ -2535,7 +2510,7 @@ class MysqlDatasQuery:
2535
2510
  }
2536
2511
  __res = []
2537
2512
  for year in range(2024, datetime.datetime.today().year + 1):
2538
- df_tm = self.download.data_to_df(
2513
+ df_tm = self.download_manager.data_to_df(
2539
2514
  db_name='推广数据2',
2540
2515
  table_name=f'营销场景报表_{year}',
2541
2516
  start_date=start_date,
@@ -2560,7 +2535,7 @@ class MysqlDatasQuery:
2560
2535
  # 奥莱店
2561
2536
  __res = []
2562
2537
  for year in range(2024, datetime.datetime.today().year + 1):
2563
- df_al = self.download.data_to_df(
2538
+ df_al = self.download_manager.data_to_df(
2564
2539
  db_name='推广数据_奥莱店',
2565
2540
  table_name=f'营销场景报表_{year}',
2566
2541
  start_date=start_date,
@@ -2586,7 +2561,7 @@ class MysqlDatasQuery:
2586
2561
  # sj圣积
2587
2562
  __res = []
2588
2563
  for year in range(2025, datetime.datetime.today().year + 1):
2589
- df_sj = self.download.data_to_df(
2564
+ df_sj = self.download_manager.data_to_df(
2590
2565
  db_name='推广数据_圣积天猫店',
2591
2566
  table_name=f'营销场景报表_{year}',
2592
2567
  start_date=start_date,
@@ -2612,7 +2587,7 @@ class MysqlDatasQuery:
2612
2587
  # 淘宝店
2613
2588
  __res = []
2614
2589
  for year in range(2024, datetime.datetime.today().year + 1):
2615
- df_tb = self.download.data_to_df(
2590
+ df_tb = self.download_manager.data_to_df(
2616
2591
  db_name='推广数据_淘宝店',
2617
2592
  table_name=f'营销场景报表_{year}',
2618
2593
  start_date=start_date,
@@ -2651,7 +2626,7 @@ class MysqlDatasQuery:
2651
2626
  }
2652
2627
  __res = []
2653
2628
  for year in range(2024, datetime.datetime.today().year + 1):
2654
- df_tb_qzt = self.download.data_to_df(
2629
+ df_tb_qzt = self.download_manager.data_to_df(
2655
2630
  db_name='推广数据_淘宝店',
2656
2631
  table_name=f'全站推广报表_{year}',
2657
2632
  start_date=start_date,
@@ -2701,7 +2676,7 @@ class MysqlDatasQuery:
2701
2676
  }
2702
2677
  __res = []
2703
2678
  for year in range(2024, datetime.datetime.today().year + 1):
2704
- df_tm_pxb = self.download.data_to_df(
2679
+ df_tm_pxb = self.download_manager.data_to_df(
2705
2680
  db_name='推广数据2',
2706
2681
  table_name=f'品销宝_{year}',
2707
2682
  start_date=start_date,
@@ -2741,7 +2716,7 @@ class MysqlDatasQuery:
2741
2716
  }
2742
2717
  __res = []
2743
2718
  for year in range(2024, datetime.datetime.today().year + 1):
2744
- df_tm_living = self.download.data_to_df(
2719
+ df_tm_living = self.download_manager.data_to_df(
2745
2720
  db_name='推广数据2',
2746
2721
  table_name=f'超级直播报表_人群_{year}',
2747
2722
  start_date=start_date,
@@ -2783,7 +2758,7 @@ class MysqlDatasQuery:
2783
2758
  }
2784
2759
  __res = []
2785
2760
  for year in range(2024, datetime.datetime.today().year + 1):
2786
- df_jd = self.download.data_to_df(
2761
+ df_jd = self.download_manager.data_to_df(
2787
2762
  db_name='京东数据3',
2788
2763
  table_name=f'推广数据_京准通_{year}',
2789
2764
  start_date=start_date,
@@ -2821,7 +2796,7 @@ class MysqlDatasQuery:
2821
2796
  '核心位置点击量': 1,
2822
2797
  '店铺名称': 1,
2823
2798
  }
2824
- df_jd_qzyx = self.download.data_to_df(
2799
+ df_jd_qzyx = self.download_manager.data_to_df(
2825
2800
  db_name='京东数据3',
2826
2801
  table_name='推广数据_全站营销',
2827
2802
  start_date=start_date,
@@ -2862,7 +2837,7 @@ class MysqlDatasQuery:
2862
2837
  }
2863
2838
  __res = []
2864
2839
  for year in range(2025, datetime.datetime.today().year + 1):
2865
- df_jd_ziying = self.download.data_to_df(
2840
+ df_jd_ziying = self.download_manager.data_to_df(
2866
2841
  db_name='京东数据3',
2867
2842
  table_name=f'推广数据_京准通_自营店_{year}',
2868
2843
  start_date=start_date,
@@ -2952,25 +2927,25 @@ class MysqlDatasQuery:
2952
2927
  '成交笔数': 'int',
2953
2928
  '成交金额': 'decimal(12,2)',
2954
2929
  }
2955
- if not self.update_service:
2956
- return
2957
- min_date = df['日期'].min().strftime('%Y-%m-%d')
2958
- max_date = df['日期'].max().strftime('%Y-%m-%d')
2959
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
2960
- m_engine.df_to_mysql(
2961
- df=df,
2962
- db_name=db_name,
2963
- table_name=table_name,
2964
- # icm_update=['日期', '店铺名称', '营销场景', '花费', '展现量', '点击量'], # 增量更新, 在聚合数据中使用,其他不要用
2965
- move_insert=True, # 先删除,再插入
2966
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
2967
- count=None,
2968
- filename=None, # 用来追踪处理进度
2969
- set_typ=set_typ
2970
- )
2971
- return True
2930
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2931
+ return df, {
2932
+ 'db_name': db_name,
2933
+ 'table_name': table_name,
2934
+ 'set_typ': set_typ,
2935
+ 'primary_keys': [], # 创建唯一主键
2936
+ 'check_duplicate': False, # 检查重复数据
2937
+ 'duplicate_columns': [], # 指定排重的组合键
2938
+ 'update_on_duplicate': True, # 更新旧数据
2939
+ 'allow_null': False, # 允许插入空值
2940
+ 'partition_by': None, # 分表方式
2941
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
2942
+ 'indexes': [], # 普通索引列
2943
+ 'transaction_mode': 'batch', # 事务模式
2944
+ 'unique_keys': [['日期', '店铺名称', '营销场景']], # 唯一约束列表
2945
+ }
2972
2946
 
2973
2947
  @try_except
2948
+ @upload_data_decorator()
2974
2949
  def aikucun_bd_spu(self, db_name='聚合数据', table_name='爱库存_商品spu榜单'):
2975
2950
  start_date, end_date = self.months_data(num=self.months)
2976
2951
  projection = {
@@ -3011,7 +2986,7 @@ class MysqlDatasQuery:
3011
2986
  '更新时间': 1,
3012
2987
  }
3013
2988
  projection = {}
3014
- df = self.download.data_to_df(
2989
+ df = self.download_manager.data_to_df(
3015
2990
  db_name='爱库存2',
3016
2991
  table_name='spu榜单',
3017
2992
  start_date=start_date,
@@ -3043,26 +3018,28 @@ class MysqlDatasQuery:
3043
3018
  '数据更新时间': 'timestamp',
3044
3019
  '更新时间': 'timestamp',
3045
3020
  }
3046
- min_date = df['日期'].min()
3047
- max_date = df['日期'].max()
3048
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
3049
- m_engine.df_to_mysql(
3050
- df=df,
3051
- db_name=db_name,
3052
- table_name=table_name,
3053
- icm_update=[], # 增量更新, 在聚合数据中使用,其他不要用
3054
- move_insert=True, # 先删除,再插入
3055
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
3056
- count=None,
3057
- filename=None, # 用来追踪处理进度
3058
- set_typ=set_typ
3059
- )
3060
- return True
3021
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
3022
+ return df, {
3023
+ 'db_name': db_name,
3024
+ 'table_name': table_name,
3025
+ 'set_typ': set_typ,
3026
+ 'primary_keys': [], # 创建唯一主键
3027
+ 'check_duplicate': False, # 检查重复数据
3028
+ 'duplicate_columns': [], # 指定排重的组合键
3029
+ 'update_on_duplicate': True, # 更新旧数据
3030
+ 'allow_null': False, # 允许插入空值
3031
+ 'partition_by': None, # 分表方式
3032
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
3033
+ 'indexes': [], # 普通索引列
3034
+ 'transaction_mode': 'batch', # 事务模式
3035
+ 'unique_keys': [['日期', '店铺名称', '营销场景']], # 唯一约束列表
3036
+ }
3061
3037
 
3038
+ @upload_data_decorator()
3062
3039
  def deeplink(self, db_name='聚合数据', table_name='达摩盘_deeplink人群洞察'):
3063
3040
  start_date, end_date = self.months_data(num=self.months)
3064
3041
  projection = {}
3065
- df = self.download.data_to_df(
3042
+ df = self.download_manager.data_to_df(
3066
3043
  db_name='达摩盘3',
3067
3044
  table_name='店铺deeplink人群洞察',
3068
3045
  start_date=start_date,
@@ -3070,8 +3047,6 @@ class MysqlDatasQuery:
3070
3047
  projection=projection,
3071
3048
  )
3072
3049
  df.drop_duplicates(subset=['日期', '人群类型', '店铺名称', '人群规模', '广告投入金额'], keep='last', inplace=True, ignore_index=True)
3073
- if not self.update_service:
3074
- return
3075
3050
  set_typ = {
3076
3051
  '日期': 'date',
3077
3052
  '人群类型': 'varchar(100)',
@@ -3092,23 +3067,25 @@ class MysqlDatasQuery:
3092
3067
  '长周期成交价值': 'decimal(13, 2)',
3093
3068
  '达摩盘id': 'int',
3094
3069
  }
3095
- min_date = df['日期'].min()
3096
- max_date = df['日期'].max()
3097
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
3098
- m_engine.df_to_mysql(
3099
- df=df,
3100
- db_name=db_name,
3101
- table_name=table_name,
3102
- # icm_update=['日期', '人群类型', '店铺名称', '人群规模', '广告投入金额'], # 增量更新, 在聚合数据中使用,其他不要用
3103
- move_insert=True, # 先删除,再插入
3104
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
3105
- count=None,
3106
- filename=None, # 用来追踪处理进度
3107
- set_typ=set_typ
3108
- )
3109
- return True
3070
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
3071
+ return df, {
3072
+ 'db_name': db_name,
3073
+ 'table_name': table_name,
3074
+ 'set_typ': set_typ,
3075
+ 'primary_keys': [], # 创建唯一主键
3076
+ 'check_duplicate': False, # 检查重复数据
3077
+ 'duplicate_columns': [], # 指定排重的组合键
3078
+ 'update_on_duplicate': True, # 更新旧数据
3079
+ 'allow_null': False, # 允许插入空值
3080
+ 'partition_by': None, # 分表方式
3081
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
3082
+ 'indexes': [], # 普通索引列
3083
+ 'transaction_mode': 'batch', # 事务模式
3084
+ 'unique_keys': [['日期', '人群类型', '店铺名称', '人群规模']], # 唯一约束列表
3085
+ }
3110
3086
 
3111
3087
  # @try_except
3088
+ @upload_data_decorator()
3112
3089
  def dmp_crowd(self, db_name='聚合数据', table_name='达摩盘_人群报表'):
3113
3090
  start_date, end_date = self.months_data(num=self.months)
3114
3091
  projection = {
@@ -3120,7 +3097,7 @@ class MysqlDatasQuery:
3120
3097
  '用户性别': 1,
3121
3098
  }
3122
3099
  # projection = {}
3123
- df_crowd = self.download.data_to_df(
3100
+ df_crowd = self.download_manager.data_to_df(
3124
3101
  db_name='达摩盘3',
3125
3102
  table_name='我的人群属性',
3126
3103
  start_date=start_date,
@@ -3135,7 +3112,7 @@ class MysqlDatasQuery:
3135
3112
  projection = {}
3136
3113
  __res = []
3137
3114
  for year in range(2024, datetime.datetime.today().year + 1):
3138
- df_dmp = self.download.data_to_df(
3115
+ df_dmp = self.download_manager.data_to_df(
3139
3116
  db_name='达摩盘3',
3140
3117
  table_name=f'dmp人群报表_{year}',
3141
3118
  start_date=start_date,
@@ -3201,21 +3178,22 @@ class MysqlDatasQuery:
3201
3178
  '消费能力等级': 'varchar(100)',
3202
3179
  '用户性别': 'varchar(100)',
3203
3180
  }
3204
- min_date = df['日期'].min()
3205
- max_date = df['日期'].max()
3206
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
3207
- m_engine.df_to_mysql(
3208
- df=df,
3209
- db_name=db_name,
3210
- table_name=table_name,
3211
- icm_update=[], # 增量更新, 在聚合数据中使用,其他不要用
3212
- move_insert=True, # 先删除,再插入
3213
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
3214
- count=None,
3215
- filename=None, # 用来追踪处理进度
3216
- set_typ=set_typ,
3217
- )
3218
- return True
3181
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
3182
+ return df, {
3183
+ 'db_name': db_name,
3184
+ 'table_name': table_name,
3185
+ 'set_typ': set_typ,
3186
+ 'primary_keys': [], # 创建唯一主键
3187
+ 'check_duplicate': False, # 检查重复数据
3188
+ 'duplicate_columns': [], # 指定排重的组合键
3189
+ 'update_on_duplicate': True, # 更新旧数据
3190
+ 'allow_null': False, # 允许插入空值
3191
+ 'partition_by': None, # 分表方式
3192
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
3193
+ 'indexes': [], # 普通索引列
3194
+ 'transaction_mode': 'batch', # 事务模式
3195
+ 'unique_keys': [['日期', '店铺名称', '人群id', '营销渠道', '计划基础信息']], # 唯一约束列表
3196
+ }
3219
3197
 
3220
3198
  @try_except
3221
3199
  def ret_keyword(self, keyword, as_file=False):
@@ -3513,110 +3491,7 @@ class MysqlDatasQuery:
3513
3491
  return result
3514
3492
 
3515
3493
  # @try_except
3516
- def performance(self, db_name, table_name, bb_tg=True):
3517
-
3518
- tg= [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '天猫_主体报表'][0]
3519
- syj = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '生意经_宝贝指标'][0]
3520
- idbm = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '商品id编码表'][0]
3521
- pic = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '商品id图片对照表'][0]
3522
- cost = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '商品成本'][0]
3523
-
3524
- # 由于推广表之前根据场景、营销渠道等聚合的,这里不含这些字段所以要进一步聚合
3525
- tg = tg.groupby(
3526
- ['日期', '店铺名称', '商品id'],
3527
- as_index=False).agg(
3528
- **{
3529
- '花费': ('花费', np.sum),
3530
- '成交金额': ('成交金额', np.sum),
3531
- '直接成交金额': ('直接成交金额', np.sum),
3532
- }
3533
- )
3534
- # 4. 生意经,推广表聚合
3535
- if bb_tg is True:
3536
- # 生意经合并推广表,完整的数据表,包含全店所有推广、销售数据
3537
- df = pd.merge(syj, tg, how='left', left_on=['日期', '店铺名称', '宝贝id'], right_on=['日期', '店铺名称', '商品id'])
3538
- df.drop(labels='商品id', axis=1, inplace=True) # 因为生意经中的宝贝 id 列才是完整的
3539
- df.rename(columns={'宝贝id': '商品id'}, inplace=True)
3540
- else:
3541
- # 推广表合并生意经 , 以推广数据为基准,销售数据不齐全
3542
- df = pd.merge(tg, syj, how='left', left_on=['日期', '店铺名称', '商品id'], right_on=['日期', '店铺名称', '宝贝id'])
3543
- df.drop(labels='宝贝id', axis=1, inplace=True)
3544
-
3545
- df['商品id'] = df['商品id'].astype('int64')
3546
- df = df[df['花费'] > 0]
3547
- df = df.groupby(
3548
- ['日期', '店铺名称', '商品id'],
3549
- as_index=False).agg(
3550
- **{
3551
- '花费': ('花费', np.sum),
3552
- '成交金额': ('成交金额', np.sum),
3553
- '直接成交金额': ('直接成交金额', np.sum),
3554
- '销售额': ('销售额', np.sum),
3555
- '销售量': ('销售量', np.sum),
3556
- '退款额_发货后': ('退款额_发货后', np.sum),
3557
- '退货量_发货后': ('退货量_发货后', np.sum),
3558
- }
3559
- )
3560
-
3561
- idbm['宝贝id'] = idbm['宝贝id'].astype('int64')
3562
- # 1. id 编码表合并图片表
3563
- df_cb = pd.merge(idbm, pic, how='left', left_on='宝贝id', right_on='商品id')
3564
- df_cb = df_cb[['宝贝id', '商家编码', '商品图片']]
3565
- # 2. df 合并商品成本表
3566
- df_cb = pd.merge(df_cb, cost, how='left', left_on='商家编码', right_on='款号')
3567
- df_cb = df_cb[['宝贝id', '商家编码', '商品图片', '成本价']]
3568
- # 3. 合并 df
3569
- df = pd.merge(df, df_cb, how='left', left_on='商品id', right_on='宝贝id')
3570
- df.drop(labels='宝贝id', axis=1, inplace=True)
3571
-
3572
- # df.drop_duplicates(subset=['日期', '店铺名称', '商品id', '花费', '销售额'], keep='last', inplace=True, ignore_index=True)
3573
- df.fillna(0, inplace=True)
3574
- df['成本价'] = df['成本价'].astype('float64')
3575
- df['销售额'] = df['销售额'].astype('float64')
3576
- df['销售量'] = df['销售量'].astype('int64')
3577
- df['商品成本'] = df.apply(lambda x: (x['成本价'] + x['销售额']/x['销售量'] * 0.11 + 6) * x['销售量'] if x['销售量'] > 0 else 0, axis=1)
3578
- df['商品毛利'] = df.apply(lambda x: x['销售额'] - x['商品成本'], axis=1)
3579
- df['毛利率'] = df.apply(lambda x: round((x['销售额'] - x['商品成本']) / x['销售额'], 4) if x['销售额'] > 0 else 0, axis=1)
3580
- df['盈亏'] = df.apply(lambda x: x['商品毛利'] - x['花费'], axis=1)
3581
- [df[col].apply(lambda x: '0' if str(x) == '' else x) for col in df.columns.tolist()]
3582
- set_typ = {
3583
- '日期': 'date',
3584
- '店铺名称': 'varchar(100)',
3585
- '商品id': 'bigint',
3586
- '销售额': 'decimal(12,2)',
3587
- '销售量': 'int',
3588
- '退款额_发货后': 'decimal(12,2)',
3589
- '退货量_发货后': 'int',
3590
- '花费': 'decimal(12,2)',
3591
- '成交金额': 'decimal(12,2)',
3592
- '直接成交金额': 'decimal(12,2)',
3593
- '商家编码': 'varchar(100)',
3594
- '商品图片': 'varchar(255)',
3595
- '成本价': 'decimal(10,2)',
3596
- '商品成本': 'decimal(10,2)',
3597
- '商品毛利': 'decimal(10,2)',
3598
- '毛利率': 'decimal(12,4)',
3599
- '盈亏': 'decimal(12,4)',
3600
- }
3601
- if not self.update_service:
3602
- return
3603
- min_date = df['日期'].min()
3604
- max_date = df['日期'].max()
3605
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
3606
- m_engine.df_to_mysql(
3607
- df=df,
3608
- db_name=db_name,
3609
- table_name=table_name,
3610
- icm_update=[], # 增量更新, 在聚合数据中使用,其他不要用
3611
- move_insert=True, # 先删除,再插入
3612
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
3613
- count=None,
3614
- filename=None, # 用来追踪处理进度
3615
- set_typ=set_typ,
3616
- )
3617
- return True
3618
-
3619
- # @try_except
3494
+ @upload_data_decorator()
3620
3495
  def performance_concat(self, db_name, table_name, bb_tg=True):
3621
3496
  tg = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '天猫汇总表调用'][0]
3622
3497
  zb = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '天猫_超级直播'][0]
@@ -3697,92 +3572,23 @@ class MysqlDatasQuery:
3697
3572
  '直接成交金额': 'decimal(12,2)',
3698
3573
  '自然流量曝光量': 'int',
3699
3574
  }
3700
- if not self.update_service:
3701
- return
3702
3575
  df['日期'] = pd.to_datetime(df['日期'], format='%Y-%m-%d', errors='ignore')
3703
- min_date = df['日期'].min()
3704
- max_date = df['日期'].max()
3705
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
3706
- m_engine.df_to_mysql(
3707
- df=df,
3708
- db_name=db_name,
3709
- table_name=table_name,
3710
- icm_update=[], # 增量更新, 在聚合数据中使用,其他不要用
3711
- move_insert=True, # 先删除,再插入
3712
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
3713
- count=None,
3714
- filename=None, # 用来追踪处理进度
3715
- set_typ=set_typ,
3716
- )
3717
- return True
3718
-
3719
- # @try_except
3720
- def performance_jd(self, db_name, table_name, jd_tg=True, ):
3721
- jdtg = [item['数据主体'] for item in self.pf_datas_jd if item['集合名称'] == '京东_京准通'][0]
3722
- sku_sales = [item['数据主体'] for item in self.pf_datas_jd if item['集合名称'] == '京东_sku_商品明细'][0]
3723
- cost = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '商品成本'][0]
3724
- jdtg = jdtg[jdtg['花费'] > 0]
3725
- jdtg = jdtg.groupby(['日期', '跟单sku_id'],
3726
- as_index=False).agg(
3727
- **{
3728
- '花费': ('花费', np.sum)
3729
- }
3730
- )
3731
- df = pd.merge(sku_sales, cost, how='left', left_on='货号', right_on='款号')
3732
- df = df[['日期', '商品id', '货号', '成交单量', '成交金额', '成本价']]
3733
- df['商品id'] = df['商品id'].astype(str)
3734
- jdtg['跟单sku_id'] = jdtg['跟单sku_id'].astype(str)
3735
- jdtg = jdtg.astype({'日期': 'datetime64[ns]'}, errors='raise')
3736
- df = df.astype({'日期': 'datetime64[ns]'}, errors='raise')
3737
- if jd_tg is True:
3738
- # 完整的数据表,包含全店所有推广、销售数据
3739
- df = pd.merge(df, jdtg, how='left', left_on=['日期', '商品id'], right_on=['日期', '跟单sku_id']) # df 合并推广表
3740
- else:
3741
- df = pd.merge(jdtg, df, how='left', left_on=['日期', '跟单sku_id'], right_on=['日期', '商品id']) # 推广表合并 df
3742
- df = df[['日期', '跟单sku_id', '花费', '货号', '成交单量', '成交金额', '成本价']]
3743
- df.fillna(0, inplace=True)
3744
- df['成本价'] = df['成本价'].astype('float64')
3745
- df['成交金额'] = df['成交金额'].astype('float64')
3746
- df['花费'] = df['花费'].astype('float64')
3747
- df['成交单量'] = df['成交单量'].astype('int64')
3748
- df['商品成本'] = df.apply(
3749
- lambda x: (x['成本价'] + x['成交金额'] / x['成交单量'] * 0.11 + 6) * x['成交单量'] if x['成交单量'] > 0 else 0,
3750
- axis=1)
3751
- df['商品毛利'] = df.apply(lambda x: x['成交金额'] - x['商品成本'], axis=1)
3752
- df['毛利率'] = df.apply(
3753
- lambda x: round((x['成交金额'] - x['商品成本']) / x['成交金额'], 4) if x['成交金额'] > 0 else 0, axis=1)
3754
- df['盈亏'] = df.apply(lambda x: x['商品毛利'] - x['花费'], axis=1)
3755
- [df[col].apply(lambda x: '0' if str(x) == '' else x) for col in df.columns.tolist()]
3756
- set_typ = {
3757
- '日期': 'date',
3758
- '跟单sku_id': 'bigint',
3759
- '花费': 'decimal(12,2)',
3760
- '货号': 'varchar(100)',
3761
- '成交单量': 'int',
3762
- '成交金额': 'decimal(12,2)',
3763
- '成本价': 'decimal(10,2)',
3764
- '商品成本': 'decimal(10,2)',
3765
- '商品毛利': 'decimal(10,2)',
3766
- '毛利率': 'decimal(12,4)',
3767
- '盈亏': 'decimal(12,4)',
3768
- }
3769
- if not self.update_service:
3770
- return
3771
- min_date = df['日期'].min().strftime("%Y-%m-%d")
3772
- max_date = df['日期'].max().strftime("%Y-%m-%d")
3773
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name} -> {min_date}~{max_date}')
3774
- m_engine.df_to_mysql(
3775
- df=df,
3776
- db_name=db_name,
3777
- table_name=table_name,
3778
- icm_update=[], # 增量更新, 在聚合数据中使用,其他不要用
3779
- move_insert=True, # 先删除,再插入
3780
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
3781
- count=None,
3782
- filename=None, # 用来追踪处理进度
3783
- set_typ=set_typ,
3784
- )
3785
- return True
3576
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
3577
+ return df, {
3578
+ 'db_name': db_name,
3579
+ 'table_name': table_name,
3580
+ 'set_typ': set_typ,
3581
+ 'primary_keys': [], # 创建唯一主键
3582
+ 'check_duplicate': False, # 检查重复数据
3583
+ 'duplicate_columns': [], # 指定排重的组合键
3584
+ 'update_on_duplicate': True, # 更新旧数据
3585
+ 'allow_null': False, # 允许插入空值
3586
+ 'partition_by': None, # 分表方式
3587
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
3588
+ 'indexes': [], # 普通索引列
3589
+ 'transaction_mode': 'batch', # 事务模式
3590
+ 'unique_keys': [['日期', '店铺名称', '推广渠道', '营销场景', '商品id']], # 唯一约束列表
3591
+ }
3786
3592
 
3787
3593
 
3788
3594
  def get_day_of_month(num):
@@ -3798,6 +3604,7 @@ def get_day_of_month(num):
3798
3604
  return _firstDay, _lastDay
3799
3605
 
3800
3606
 
3607
+ @upload_data_decorator()
3801
3608
  def date_table():
3802
3609
  """
3803
3610
  生成 pbix 使用的日期表
@@ -3869,23 +3676,31 @@ def date_table():
3869
3676
  '索引': 'int',
3870
3677
  '月索引': 'int',
3871
3678
  }
3872
- m_engine.df_to_mysql(
3873
- df=df,
3874
- db_name='聚合数据',
3875
- table_name='日期表',
3876
- move_insert=True, # 先删除,再插入
3877
- df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
3878
- set_typ=set_typ,
3879
- )
3679
+ return df, {
3680
+ 'db_name': '聚合数据',
3681
+ 'table_name': '日期表',
3682
+ 'set_typ': set_typ,
3683
+ 'primary_keys': [], # 创建唯一主键
3684
+ 'check_duplicate': False, # 检查重复数据
3685
+ 'duplicate_columns': [], # 指定排重的组合键
3686
+ 'update_on_duplicate': True, # 更新旧数据
3687
+ 'allow_null': False, # 允许插入空值
3688
+ 'partition_by': None, # 分表方式
3689
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
3690
+ 'indexes': [], # 普通索引列
3691
+ 'transaction_mode': 'batch', # 事务模式
3692
+ 'unique_keys': [['日期']], # 唯一约束列表
3693
+ }
3880
3694
 
3881
3695
 
3882
- def query1(months=1, less_dict=[]):
3696
+ def query1(months=1, less_dict=None, download_manager=None):
3697
+ if less_dict is None:
3698
+ less_dict = []
3883
3699
  if months == 0:
3884
- logger.info(f'months 不建议为 0 ')
3700
+ logger.info('months 不建议为 0')
3885
3701
  return
3886
- sdq = MysqlDatasQuery() # 实例化数据处理类
3702
+ sdq = MysqlDatasQuery(download_manager=download_manager) # 实例化数据处理类
3887
3703
  sdq.months = months # 设置数据周期, 1 表示近 2 个月
3888
- sdq.update_service = True # 调试时加,true: 将数据写入 mysql 服务器
3889
3704
 
3890
3705
  # 依赖表 -- >>
3891
3706
  sdq.tg_wxt(db_name='聚合数据', table_name='天猫_主体报表')
@@ -3907,19 +3722,17 @@ def query1(months=1, less_dict=[]):
3907
3722
  sdq.spu_sales(db_name='聚合数据', table_name='京东_spu_商品明细')
3908
3723
  sdq.zb_ccfx(db_name='聚合数据', table_name='生意参谋_直播场次分析')
3909
3724
  sdq.tg_by_day(db_name='聚合数据', table_name='多店推广场景_按日聚合')
3910
- # sdq.performance(bb_tg=True, db_name='聚合数据', table_name='_全店商品销售') # _全店商品销售
3911
- # sdq.performance(bb_tg=False, db_name='聚合数据', table_name='_推广商品销售') # _推广商品销售
3912
- # sdq.performance_jd(jd_tg=False, db_name='聚合数据', table_name='_京东_推广商品销售') # _推广商品销售
3913
3725
  sdq.performance_concat(bb_tg=False, db_name='聚合数据', table_name='天猫_推广汇总') # _推广商品销售
3914
3726
 
3915
3727
 
3916
- def query2(months=1, less_dict=[]):
3728
+ def query2(months=1, less_dict=None, download_manager=None):
3729
+ if less_dict is None:
3730
+ less_dict = []
3917
3731
  if months == 0:
3918
- logger.info(f'months 不建议为 0 ')
3732
+ logger.info('months 不建议为 0')
3919
3733
  return
3920
- sdq = MysqlDatasQuery() # 实例化数据处理类
3734
+ sdq = MysqlDatasQuery(download_manager=download_manager) # 实例化数据处理类
3921
3735
  sdq.months = months # 设置数据周期, 1 表示近 2 个月
3922
- sdq.update_service = True # 调试时加,true: 将数据写入 mysql 服务器
3923
3736
  sdq.dplyd(db_name='聚合数据', table_name='店铺流量来源构成')
3924
3737
  sdq.tg_rqbb(db_name='聚合数据', table_name='天猫_人群报表')
3925
3738
  sdq.tg_gjc(db_name='聚合数据', table_name='天猫_关键词报表')
@@ -3930,98 +3743,32 @@ def query2(months=1, less_dict=[]):
3930
3743
  sdq.deeplink(db_name='聚合数据', table_name='达摩盘_deeplink人群洞察')
3931
3744
 
3932
3745
 
3933
- def query3(months=1, less_dict=[]):
3746
+ def query3(months=1, less_dict=None, download_manager=None):
3747
+ if less_dict is None:
3748
+ less_dict = []
3934
3749
  if months == 0:
3935
- logger.info(f'months 不建议为 0 ')
3750
+ logger.info('months 不建议为 0')
3936
3751
  return
3937
- sdq = MysqlDatasQuery() # 实例化数据处理类
3752
+ sdq = MysqlDatasQuery(download_manager=download_manager) # 实例化数据处理类
3938
3753
  sdq.months = months # 设置数据周期, 1 表示近 2 个月
3939
- sdq.update_service = True # 调试时加,true: 将数据写入 mysql 服务器
3940
3754
  sdq.spph(db_name='聚合数据', table_name='天猫_商品排行')
3941
3755
 
3942
3756
 
3943
- def op_data(db_name_lists, days: int = 63, is_mongo=True, is_mysql=True):
3944
- # Mysql
3945
- if is_mysql:
3946
- s = mysql.OptimizeDatas(username=username, password=password, host=host, port=port)
3947
- s.db_name_lists = db_name_lists
3948
- s.days = days
3949
- s.optimize_list()
3950
-
3951
-
3952
3757
  def main(days=150, months=3):
3953
- """
3954
- days: 清理聚合数据的日期长度,days 最好大于 3 * (months +1)
3955
- months: 生成聚合数据的长度
3956
- """
3957
3758
  # 1. 更新日期表 更新货品年份基准表, 属性设置 3 - 货品年份基准
3958
3759
  date_table()
3959
3760
 
3960
- # 清理非聚合数据库
3961
- db_list = [
3962
- "京东数据3",
3963
- "属性设置3",
3964
- "推广数据2",
3965
- "推广数据_淘宝店",
3966
- "推广数据_奥莱店",
3967
- "推广数据_圣积天猫店",
3968
- "爱库存2",
3969
- "生意参谋3",
3970
- "生意经3",
3971
- "达摩盘3",
3972
- '人群画像2',
3973
- '商品人群画像2',
3974
- '市场数据3',
3975
- '回传数据',
3976
- '数据引擎2',
3977
- ]
3978
- # 使用 ThreadPoolExecutor 来并行运行
3979
- # with concurrent.futures.ThreadPoolExecutor() as executor:
3980
- with concurrent.futures.ProcessPoolExecutor() as executor:
3981
- for step in range(len(db_list)):
3982
- future_to_function = {
3983
- executor.submit(
3984
- op_data,
3985
- days=31,
3986
- is_mongo=False,
3987
- is_mysql=True,
3988
- db_name_lists=[db_list[step]],
3989
- ),
3990
- }
3991
- # # 等待所有任务完成并获取执行结果
3992
- # for future in concurrent.futures.as_completed(future_to_function):
3993
- # future.result()
3994
-
3995
3761
  # 2. 数据聚合
3996
- query_list = [query1, query2, query3]
3997
- # 使用 ThreadPoolExecutor 来并行运行
3998
- # with concurrent.futures.ThreadPoolExecutor() as executor:
3999
- with concurrent.futures.ProcessPoolExecutor() as executor:
4000
- for func_query in query_list:
4001
- future_to_function = {
4002
- executor.submit(
4003
- func_query,
4004
- months=months,
4005
- less_dict=[],
4006
- ),
4007
- }
4008
- # query_(months=months)
4009
- time.sleep(10)
4010
-
4011
- # 3. 清理聚合数据
4012
- op_data(
4013
- db_name_lists=['聚合数据'],
4014
- days=days, # 清理聚合数据的日期长度
4015
- is_mongo=False,
4016
- is_mysql=True,
4017
- )
4018
-
4019
-
4020
- def test():
4021
- sdq = MysqlDatasQuery() # 实例化数据处理类
4022
- sdq.months = 1 # 设置数据周期, 1 表示近 2 个月
4023
- sdq.update_service = True # 调试时加,true: 将数据写入 mysql 服务器
4024
- sdq.spph(db_name='聚合数据', table_name='天猫_商品排行')
3762
+ download_manager = s_query.QueryDatas(
3763
+ username=username,
3764
+ password=password,
3765
+ host=host,
3766
+ port=port,
3767
+ maxconnections=30,
3768
+ )
3769
+ query1(download_manager=download_manager, months=months)
3770
+ query2(download_manager=download_manager, months=months)
3771
+ query3(download_manager=download_manager, months=months)
4025
3772
 
4026
3773
 
4027
3774
  if __name__ == '__main__':
@@ -4029,3 +3776,5 @@ if __name__ == '__main__':
4029
3776
  days=150, # 清理聚合数据的日期长度
4030
3777
  months=3 # 生成聚合数据的长度
4031
3778
  )
3779
+
3780
+ # date_table()