mdbq 4.0.2__py3-none-any.whl → 4.0.4__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
@@ -13,17 +14,15 @@ import platform
13
14
  import os
14
15
  import time
15
16
  import calendar
16
- import concurrent.futures
17
-
18
- """
19
-
20
- """
17
+ from collections.abc import Mapping, Sequence
18
+ import inspect
21
19
 
22
20
  dir_path = os.path.expanduser("~")
23
21
  config_file = os.path.join(dir_path, 'spd.txt')
24
22
  content = config.read_config(file_path=config_file)
25
23
  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')
24
+ host = 'localhost'
25
+ uld = uploader.MySQLUploader(username=username, password=password, host=host, port=int(port), pool_size=10)
27
26
 
28
27
  logger = mylogger.MyLogger(
29
28
  logging_mode='file',
@@ -38,15 +37,170 @@ logger = mylogger.MyLogger(
38
37
  )
39
38
 
40
39
 
40
+ def reorder_columns(df: pd.DataFrame, set_type) -> pd.DataFrame:
41
+ """
42
+ 调整DataFrame的列顺序,按照set_type中的顺序排列,忽略大小写,set_type中不存在的列自动跳过。
43
+ set_type可以是列表或字典(此时用字典的键名作为顺序)。
44
+ 不改变数据和数据类型。
45
+ 如果 set_type 为 None、空列表或空字典,则直接返回原 df,不做任何调整。
46
+ """
47
+ # 直接返回原 df 的情况
48
+ if set_type is None:
49
+ return df
50
+ if isinstance(set_type, Mapping) and len(set_type) == 0:
51
+ return df
52
+ if isinstance(set_type, Sequence) and not isinstance(set_type, str) and len(set_type) == 0:
53
+ return df
54
+
55
+ # 如果set_type是字典,提取其键名
56
+ if isinstance(set_type, Mapping):
57
+ col_order = list(set_type.keys())
58
+ elif isinstance(set_type, Sequence) and not isinstance(set_type, str):
59
+ col_order = list(set_type)
60
+ else:
61
+ raise ValueError("set_type must be a list or a dict (or other mapping type)")
62
+
63
+ # 构建原始列名的映射(小写->原始名)
64
+ col_map = {col.lower(): col for col in df.columns}
65
+ # 生成新顺序的列名(只保留df中存在的列,且顺序按set_type)
66
+ new_cols = []
67
+ used = set()
68
+ for col in col_order:
69
+ key = col.lower()
70
+ if key in col_map and key not in used:
71
+ new_cols.append(col_map[key])
72
+ used.add(key)
73
+ # 添加剩余未在set_type中出现的列,保持原顺序
74
+ for col in df.columns:
75
+ if col.lower() not in used:
76
+ new_cols.append(col)
77
+ # 返回新顺序的DataFrame
78
+ return df[new_cols]
79
+
80
+
81
+ def upload_data_decorator(**upload_kwargs):
82
+ """
83
+ 数据上传装饰器
84
+ :param upload_kwargs: 上传参数,支持所有 upload_data 方法的参数
85
+ :return: 装饰器函数
86
+ """
87
+ def decorator(func):
88
+ @wraps(func)
89
+ def wrapper(*args, **kwargs):
90
+ try:
91
+ # 获取 set_type 或 set_typ 参数
92
+ set_type = None
93
+ # 先从kwargs查找
94
+ for key in ['set_type', 'set_typ']:
95
+ if key in kwargs:
96
+ set_type = kwargs[key]
97
+ break
98
+ # 如果没在kwargs找到,尝试从args按参数名顺序查找
99
+ if set_type is None:
100
+ sig = inspect.signature(func)
101
+ params = list(sig.parameters)
102
+ for key in ['set_type', 'set_typ']:
103
+ if key in params:
104
+ idx = params.index(key)
105
+ if len(args) > idx:
106
+ set_type = args[idx]
107
+ break
108
+
109
+ # 执行原始函数
110
+ result = func(*args, **kwargs)
111
+
112
+ # 如果返回 None,直接返回
113
+ if result is None:
114
+ return None
115
+
116
+ # 如果返回的是 DataFrame
117
+ if isinstance(result, pd.DataFrame):
118
+ # 调整列顺序
119
+ if set_type is not None:
120
+ result = reorder_columns(result, set_type)
121
+ # 设置默认值
122
+ default_kwargs = {
123
+ 'check_duplicate': False,
124
+ 'update_on_duplicate': True,
125
+ 'allow_null': False,
126
+ 'transaction_mode': 'batch'
127
+ }
128
+ # 更新参数,优先使用装饰器参数
129
+ merged_kwargs = {**default_kwargs, **upload_kwargs}
130
+
131
+ # 上传数据
132
+ uld.upload_data(
133
+ data=result,
134
+ **merged_kwargs
135
+ )
136
+ return True
137
+
138
+ # 如果返回的是元组
139
+ elif isinstance(result, tuple):
140
+ # 检查元组长度
141
+ if len(result) < 2:
142
+ logger.warning('函数返回的元组长度小于2,直接返回原结果,不执行上传', {'函数': func.__name__})
143
+ return result
144
+
145
+ # 获取前两个元素
146
+ df, extra_kwargs = result[0], result[1]
147
+
148
+ # 检查第一个元素是否为DataFrame
149
+ if not isinstance(df, pd.DataFrame):
150
+ logger.warning('函数返回的元组第一个元素不是DataFrame,直接返回原结果,不执行上传', {'函数': func.__name__})
151
+ return result
152
+
153
+ # 调整列顺序
154
+ if set_type is not None:
155
+ df = reorder_columns(df, set_type)
156
+ # 保持元组结构
157
+ result = (df, extra_kwargs) + result[2:]
158
+ # 合并装饰器参数和函数参数
159
+ merged_kwargs = {**upload_kwargs}
160
+ merged_kwargs.update(extra_kwargs)
161
+
162
+ # 设置默认值
163
+ default_kwargs = {
164
+ 'check_duplicate': False,
165
+ 'update_on_duplicate': True,
166
+ 'allow_null': False,
167
+ 'transaction_mode': 'batch'
168
+ }
169
+ # 更新参数,优先使用装饰器参数
170
+ for key, value in default_kwargs.items():
171
+ if key not in merged_kwargs:
172
+ merged_kwargs[key] = value
173
+
174
+ # 上传数据
175
+ uld.upload_data(
176
+ data=df,
177
+ **merged_kwargs
178
+ )
179
+
180
+ # 如果元组长度大于2,返回完整元组
181
+ if len(result) > 2:
182
+ return result
183
+ return True
184
+
185
+ # 其他情况直接返回结果
186
+ return result
187
+
188
+ except Exception as e:
189
+ logger.error('数据上传失败', {'函数': func.__name__, '错误': str(e)})
190
+ return False
191
+
192
+ return wrapper
193
+ return decorator
194
+
195
+
41
196
  class MysqlDatasQuery:
42
197
  """
43
198
  从数据库中下载数据
44
199
  """
45
- def __init__(self):
200
+ def __init__(self, download_manager):
46
201
  # target_service 从哪个服务器下载数据
47
202
  self.months = 0 # 下载几个月数据, 0 表示当月, 1 是上月 1 号至今
48
- # 实例化一个下载类
49
- self.download = s_query.QueryDatas(username=username, password=password, host=host, port=port)
203
+ self.download_manager = download_manager
50
204
  self.update_service = True # 调试时加,true: 将数据写入 mysql 服务器
51
205
  self.pf_datas = []
52
206
  self.pf_datas_jd = [] # 京东聚合销售表
@@ -58,7 +212,7 @@ class MysqlDatasQuery:
58
212
  try:
59
213
  return func(*args, **kwargs)
60
214
  except Exception as e:
61
- logger.info(f'函数: {func.__name__}, 报错信息: {e}') # 将异常信息返回
215
+ logger.info('函数执行错误', {'函数': func.__name__, '错误': str(e)}) # 将异常信息返回
62
216
 
63
217
  return wrapper
64
218
 
@@ -82,7 +236,7 @@ class MysqlDatasQuery:
82
236
  }
83
237
  __res = []
84
238
  for year in range(2024, datetime.datetime.today().year+1):
85
- df = self.download.data_to_df(
239
+ df = self.download_manager.data_to_df(
86
240
  db_name='推广数据2',
87
241
  table_name=f'主体报表_{year}',
88
242
  start_date=start_date,
@@ -91,6 +245,7 @@ class MysqlDatasQuery:
91
245
  )
92
246
  __res.append(df)
93
247
  df = pd.concat(__res, ignore_index=True)
248
+
94
249
  df.rename(columns={
95
250
  '场景名字': '营销场景',
96
251
  '主体id': '商品id',
@@ -98,6 +253,7 @@ class MysqlDatasQuery:
98
253
  '总成交笔数': '成交笔数',
99
254
  '总成交金额': '成交金额'
100
255
  }, inplace=True)
256
+
101
257
  df = df.astype({
102
258
  '商品id': str,
103
259
  '花费': 'float64',
@@ -152,12 +308,7 @@ class MysqlDatasQuery:
152
308
  '直接成交笔数': 'int',
153
309
  '直接成交金额': 'decimal(12,2)',
154
310
  }
155
- # self.pf_datas.append(
156
- # {
157
- # '集合名称': table_name,
158
- # '数据主体': df[['日期', '店铺名称', '商品id', '花费', '成交金额', '直接成交金额']]
159
- # }
160
- # ) # 制作其他聚合表
311
+
161
312
  self.pf_datas.append(
162
313
  {
163
314
  '集合名称': '天猫汇总表调用',
@@ -166,21 +317,22 @@ class MysqlDatasQuery:
166
317
  '成交笔数', '成交金额', '直接成交笔数', '直接成交金额', '自然流量曝光量']]
167
318
  }
168
319
  ) # 制作其他聚合表
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,
320
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
321
+ uld.upload_data(
176
322
  db_name=db_name,
177
323
  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,
324
+ data=df,
325
+ set_typ=set_typ, # 定义列和数据类型
326
+ primary_keys=[], # 创建唯一主键
327
+ check_duplicate=False, # 检查重复数据
328
+ duplicate_columns=[], # 指定排重的组合键
329
+ update_on_duplicate=True, # 更新旧数据
330
+ allow_null=False, # 允许插入空值
331
+ partition_by=None, # 分表方式
332
+ partition_date_column='日期', # 用于分表的日期列名,默认为'日期'
333
+ indexes=[], # 普通索引列
334
+ transaction_mode='batch', # 事务模式
335
+ unique_keys=[['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量', '自然流量曝光量']], # 唯一约束列表
184
336
  )
185
337
 
186
338
  # df_pic:商品排序索引表, 给 powerbi 中的主推款排序用的,(从上月1号到今天的总花费进行排序)
@@ -215,20 +367,26 @@ class MysqlDatasQuery:
215
367
  '花费': 'decimal(12,2)',
216
368
  '更新时间': 'timestamp',
217
369
  }
218
- logger.info(f'正在更新: mysql ({host}:{port}) 属性设置3/商品索引表_主推排序调用')
219
- m_engine.df_to_mysql(
220
- df=df_pic,
370
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': '属性设置3', '表': '商品索引表_主推排序调用'})
371
+ uld.upload_data(
221
372
  db_name='属性设置3',
222
373
  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,
374
+ data=df_pic,
375
+ set_typ=set_typ, # 定义列和数据类型
376
+ primary_keys=[], # 创建唯一主键
377
+ check_duplicate=False, # 检查重复数据
378
+ duplicate_columns=[], # 指定排重的组合键
379
+ update_on_duplicate=True, # 更新旧数据
380
+ allow_null=False, # 允许插入空值
381
+ partition_by=None, # 分表方式
382
+ partition_date_column='日期', # 用于分表的日期列名,默认为'日期'
383
+ indexes=[], # 普通索引列
384
+ transaction_mode='batch', # 事务模式
385
+ unique_keys=[['商品id']], # 唯一约束列表
229
386
  )
230
387
  return True
231
388
 
389
+ @upload_data_decorator()
232
390
  def _tb_wxt(self, db_name='聚合数据', table_name='淘宝_主体报表', is_maximize=True):
233
391
  start_date, end_date = self.months_data(num=self.months)
234
392
  projection = {
@@ -248,7 +406,7 @@ class MysqlDatasQuery:
248
406
  }
249
407
  __res = []
250
408
  for year in range(2024, datetime.datetime.today().year+1):
251
- df = self.download.data_to_df(
409
+ df = self.download_manager.data_to_df(
252
410
  db_name='推广数据_淘宝店',
253
411
  table_name=f'主体报表_{year}',
254
412
  start_date=start_date,
@@ -318,25 +476,24 @@ class MysqlDatasQuery:
318
476
  '直接成交笔数': 'int',
319
477
  '直接成交金额': 'decimal(12,2)',
320
478
  }
479
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
480
+ return df, {
481
+ 'db_name': db_name,
482
+ 'table_name': table_name,
483
+ 'set_typ': set_typ,
484
+ 'primary_keys': [], # 创建唯一主键
485
+ 'check_duplicate': False, # 检查重复数据
486
+ 'duplicate_columns': [], # 指定排重的组合键
487
+ 'update_on_duplicate': True, # 更新旧数据
488
+ 'allow_null': False, # 允许插入空值
489
+ 'partition_by': None, # 分表方式
490
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
491
+ 'indexes': [], # 普通索引列
492
+ 'transaction_mode': 'batch', # 事务模式
493
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量', '自然流量曝光量']], # 唯一约束列表
494
+ }
321
495
 
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
-
496
+ @upload_data_decorator()
340
497
  def _ald_wxt(self, db_name='聚合数据', table_name='奥莱店_主体报表', is_maximize=True):
341
498
  start_date, end_date = self.months_data(num=self.months)
342
499
  projection = {
@@ -356,7 +513,7 @@ class MysqlDatasQuery:
356
513
  }
357
514
  __res = []
358
515
  for year in range(2024, datetime.datetime.today().year+1):
359
- df = self.download.data_to_df(
516
+ df = self.download_manager.data_to_df(
360
517
  db_name='推广数据_奥莱店',
361
518
  table_name=f'主体报表_{year}',
362
519
  start_date=start_date,
@@ -426,25 +583,24 @@ class MysqlDatasQuery:
426
583
  '直接成交笔数': 'int',
427
584
  '直接成交金额': 'decimal(12,2)',
428
585
  }
586
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
587
+ return df, {
588
+ 'db_name': db_name,
589
+ 'table_name': table_name,
590
+ 'set_typ': set_typ,
591
+ 'primary_keys': [], # 创建唯一主键
592
+ 'check_duplicate': False, # 检查重复数据
593
+ 'duplicate_columns': [], # 指定排重的组合键
594
+ 'update_on_duplicate': True, # 更新旧数据
595
+ 'allow_null': False, # 允许插入空值
596
+ 'partition_by': None, # 分表方式
597
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
598
+ 'indexes': [], # 普通索引列
599
+ 'transaction_mode': 'batch', # 事务模式
600
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量', '自然流量曝光量']], # 唯一约束列表
601
+ }
429
602
 
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
-
603
+ @upload_data_decorator()
448
604
  def _sj_wxt(self, db_name='聚合数据', table_name='圣积天猫店_主体报表', is_maximize=True):
449
605
  start_date, end_date = self.months_data(num=self.months)
450
606
  projection = {
@@ -464,7 +620,7 @@ class MysqlDatasQuery:
464
620
  }
465
621
  __res = []
466
622
  for year in range(2025, datetime.datetime.today().year+1):
467
- df = self.download.data_to_df(
623
+ df = self.download_manager.data_to_df(
468
624
  db_name='推广数据_圣积天猫店',
469
625
  table_name=f'主体报表_{year}',
470
626
  start_date=start_date,
@@ -534,26 +690,25 @@ class MysqlDatasQuery:
534
690
  '直接成交笔数': 'int',
535
691
  '直接成交金额': 'decimal(12,2)',
536
692
  }
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
693
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
694
+ return df, {
695
+ 'db_name': db_name,
696
+ 'table_name': table_name,
697
+ 'set_typ': set_typ,
698
+ 'primary_keys': [], # 创建唯一主键
699
+ 'check_duplicate': False, # 检查重复数据
700
+ 'duplicate_columns': [], # 指定排重的组合键
701
+ 'update_on_duplicate': True, # 更新旧数据
702
+ 'allow_null': False, # 允许插入空值
703
+ 'partition_by': None, # 分表方式
704
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
705
+ 'indexes': [], # 普通索引列
706
+ 'transaction_mode': 'batch', # 事务模式
707
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '花费', '展现量', '点击量', '自然流量曝光量']], # 唯一约束列表
708
+ }
555
709
 
556
710
  @try_except
711
+ @upload_data_decorator()
557
712
  def syj(self, db_name='聚合数据', table_name='生意经_宝贝指标'):
558
713
  start_date, end_date = self.months_data(num=self.months)
559
714
  projection = {
@@ -573,7 +728,7 @@ class MysqlDatasQuery:
573
728
  }
574
729
  __res = []
575
730
  for year in range(2024, datetime.datetime.today().year + 1):
576
- df = self.download.data_to_df(
731
+ df = self.download_manager.data_to_df(
577
732
  db_name='生意经3',
578
733
  table_name=f'宝贝指标_{year}',
579
734
  start_date=start_date,
@@ -623,31 +778,25 @@ class MysqlDatasQuery:
623
778
  '件均价': 'mediumint',
624
779
  '价格带': 'varchar(100)',
625
780
  }
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
781
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
782
+ return df, {
783
+ 'db_name': db_name,
784
+ 'table_name': table_name,
785
+ 'set_typ': set_typ,
786
+ 'primary_keys': [], # 创建唯一主键
787
+ 'check_duplicate': False, # 检查重复数据
788
+ 'duplicate_columns': [], # 指定排重的组合键
789
+ 'update_on_duplicate': True, # 更新旧数据
790
+ 'allow_null': False, # 允许插入空值
791
+ 'partition_by': None, # 分表方式
792
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
793
+ 'indexes': [], # 普通索引列
794
+ 'transaction_mode': 'batch', # 事务模式
795
+ 'unique_keys': [['日期', '店铺名称', '宝贝id']], # 唯一约束列表
796
+ }
649
797
 
650
798
  @try_except
799
+ @upload_data_decorator()
651
800
  def tg_rqbb(self, db_name='聚合数据', table_name='天猫_人群报表', is_maximize=True):
652
801
  start_date, end_date = self.months_data(num=self.months)
653
802
  projection = {
@@ -667,7 +816,7 @@ class MysqlDatasQuery:
667
816
  }
668
817
  __res = []
669
818
  for year in range(2024, datetime.datetime.today().year + 1):
670
- df = self.download.data_to_df(
819
+ df = self.download_manager.data_to_df(
671
820
  db_name='推广数据2',
672
821
  table_name=f'人群报表_{year}',
673
822
  start_date=start_date,
@@ -722,7 +871,7 @@ class MysqlDatasQuery:
722
871
  df.insert(loc=1, column='推广渠道', value='万相台无界版') # df中插入新列
723
872
 
724
873
  # 开始处理用户特征
725
- df_sx = self.download.data_to_df(
874
+ df_sx = self.download_manager.data_to_df(
726
875
  db_name='达摩盘3',
727
876
  table_name=f'我的人群属性',
728
877
  start_date=start_date,
@@ -847,23 +996,25 @@ class MysqlDatasQuery:
847
996
  '用户年龄': 'varchar(100)',
848
997
  '人群分类': 'varchar(100)',
849
998
  }
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
999
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1000
+ return df, {
1001
+ 'db_name': db_name,
1002
+ 'table_name': table_name,
1003
+ 'set_typ': set_typ,
1004
+ 'primary_keys': [], # 创建唯一主键
1005
+ 'check_duplicate': False, # 检查重复数据
1006
+ 'duplicate_columns': [], # 指定排重的组合键
1007
+ 'update_on_duplicate': True, # 更新旧数据
1008
+ 'allow_null': False, # 允许插入空值
1009
+ 'partition_by': None, # 分表方式
1010
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1011
+ 'indexes': [], # 普通索引列
1012
+ 'transaction_mode': 'batch', # 事务模式
1013
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '人群名字']], # 唯一约束列表
1014
+ }
865
1015
 
866
1016
  @try_except
1017
+ @upload_data_decorator()
867
1018
  def tg_gjc(self, db_name='聚合数据', table_name='天猫_关键词报表', is_maximize=True):
868
1019
  start_date, end_date = self.months_data(num=self.months)
869
1020
  projection = {
@@ -884,7 +1035,7 @@ class MysqlDatasQuery:
884
1035
  }
885
1036
  __res = []
886
1037
  for year in range(2024, datetime.datetime.today().year + 1):
887
- df = self.download.data_to_df(
1038
+ df = self.download_manager.data_to_df(
888
1039
  db_name='推广数据2',
889
1040
  table_name=f'关键词报表_{year}',
890
1041
  start_date=start_date,
@@ -980,21 +1131,22 @@ class MysqlDatasQuery:
980
1131
  '是否品牌词': 'varchar(100)',
981
1132
  '词分类': 'varchar(100)',
982
1133
  }
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
1134
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1135
+ return df, {
1136
+ 'db_name': db_name,
1137
+ 'table_name': table_name,
1138
+ 'set_typ': set_typ,
1139
+ 'primary_keys': [], # 创建唯一主键
1140
+ 'check_duplicate': False, # 检查重复数据
1141
+ 'duplicate_columns': [], # 指定排重的组合键
1142
+ 'update_on_duplicate': True, # 更新旧数据
1143
+ 'allow_null': False, # 允许插入空值
1144
+ 'partition_by': None, # 分表方式
1145
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1146
+ 'indexes': [], # 普通索引列
1147
+ 'transaction_mode': 'batch', # 事务模式
1148
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '商品id', '词类型', '词名字_词包名字']], # 唯一约束列表
1149
+ }
998
1150
 
999
1151
  def tg_cjzb_qzt(self, projection=None, is_maximize=True):
1000
1152
  start_date, end_date = self.months_data(num=self.months)
@@ -1012,7 +1164,7 @@ class MysqlDatasQuery:
1012
1164
  }
1013
1165
  __res = []
1014
1166
  for year in range(2025, datetime.datetime.today().year + 1):
1015
- df = self.download.data_to_df(
1167
+ df = self.download_manager.data_to_df(
1016
1168
  db_name='推广数据2',
1017
1169
  table_name=f'超级直播_全站推广报表_{year}',
1018
1170
  start_date=start_date,
@@ -1027,6 +1179,7 @@ class MysqlDatasQuery:
1027
1179
 
1028
1180
 
1029
1181
  @try_except
1182
+ @upload_data_decorator()
1030
1183
  def tg_cjzb(self, db_name='聚合数据', table_name='天猫_超级直播', is_maximize=True):
1031
1184
  start_date, end_date = self.months_data(num=self.months)
1032
1185
  projection = {
@@ -1048,7 +1201,7 @@ class MysqlDatasQuery:
1048
1201
  }
1049
1202
  __res = []
1050
1203
  for year in range(2024, datetime.datetime.today().year + 1):
1051
- df = self.download.data_to_df(
1204
+ df = self.download_manager.data_to_df(
1052
1205
  db_name='推广数据2',
1053
1206
  table_name=f'超级直播报表_人群_{year}',
1054
1207
  start_date=start_date,
@@ -1129,8 +1282,6 @@ class MysqlDatasQuery:
1129
1282
  '数据主体': df[['日期', '店铺名称', '推广渠道', '营销场景', '花费', '展现量', '观看次数', '加购量', '成交笔数', '成交金额', '直接成交笔数', '直接成交金额']]
1130
1283
  },
1131
1284
  ) # 制作其他聚合表
1132
- if not self.update_service:
1133
- return
1134
1285
  set_typ = {
1135
1286
  '日期': 'date',
1136
1287
  '推广渠道': 'varchar(100)',
@@ -1149,22 +1300,23 @@ class MysqlDatasQuery:
1149
1300
  '直接成交笔数': 'int',
1150
1301
  '直接成交金额': 'decimal(12,2)',
1151
1302
  }
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
1303
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1304
+
1305
+ return df, {
1306
+ 'db_name': db_name,
1307
+ 'table_name': table_name,
1308
+ 'set_typ': set_typ,
1309
+ 'primary_keys': [], # 创建唯一主键
1310
+ 'check_duplicate': False, # 检查重复数据
1311
+ 'duplicate_columns': [], # 指定排重的组合键
1312
+ 'update_on_duplicate': True, # 更新旧数据
1313
+ 'allow_null': False, # 允许插入空值
1314
+ 'partition_by': None, # 分表方式
1315
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1316
+ 'indexes': [], # 普通索引列
1317
+ 'transaction_mode': 'batch', # 事务模式
1318
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '人群名字', '计划名字']], # 唯一约束列表
1319
+ }
1168
1320
 
1169
1321
  @try_except
1170
1322
  def pxb_zh(self, db_name='聚合数据', table_name='天猫_品销宝账户报表', is_maximize=True):
@@ -1186,7 +1338,7 @@ class MysqlDatasQuery:
1186
1338
  }
1187
1339
  __res = []
1188
1340
  for year in range(2024, datetime.datetime.today().year + 1):
1189
- df = self.download.data_to_df(
1341
+ df = self.download_manager.data_to_df(
1190
1342
  db_name='推广数据2',
1191
1343
  table_name=f'品销宝_{year}',
1192
1344
  start_date=start_date,
@@ -1243,8 +1395,6 @@ class MysqlDatasQuery:
1243
1395
  '数据主体': df[['日期', '店铺名称', '推广渠道', '营销场景', '花费', '展现量', '点击量', '加购量', '成交笔数', '成交金额']]
1244
1396
  },
1245
1397
  ) # 制作其他聚合表
1246
- if not self.update_service:
1247
- return
1248
1398
  set_typ = {
1249
1399
  '日期': 'date',
1250
1400
  '推广渠道': 'varchar(100)',
@@ -1260,29 +1410,31 @@ class MysqlDatasQuery:
1260
1410
  '品牌搜索量': 'int',
1261
1411
  '品牌搜索人数': 'int',
1262
1412
  }
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
1413
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1414
+ return df, {
1415
+ 'db_name': db_name,
1416
+ 'table_name': table_name,
1417
+ 'set_typ': set_typ,
1418
+ 'primary_keys': [], # 创建唯一主键
1419
+ 'check_duplicate': False, # 检查重复数据
1420
+ 'duplicate_columns': [], # 指定排重的组合键
1421
+ 'update_on_duplicate': True, # 更新旧数据
1422
+ 'allow_null': False, # 允许插入空值
1423
+ 'partition_by': None, # 分表方式
1424
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1425
+ 'indexes': [], # 普通索引列
1426
+ 'transaction_mode': 'batch', # 事务模式
1427
+ 'unique_keys': [['日期', '推广渠道', '店铺名称', '营销场景', '报表类型']], # 唯一约束列表
1428
+ }
1278
1429
 
1279
1430
  @try_except
1431
+ @upload_data_decorator()
1280
1432
  def idbm_bak(self, db_name='聚合数据', table_name='商品id编码表'):
1281
1433
  """ 用生意经日数据制作商品 id 和编码对照表 """
1282
1434
  year = datetime.datetime.today().year
1283
1435
  data_values = []
1284
1436
  for year in range(2022, year+1):
1285
- data_values += self.download.columns_to_list(
1437
+ data_values += self.download_manager.columns_to_list(
1286
1438
  db_name='生意经3',
1287
1439
  table_name=f'宝贝指标_{year}',
1288
1440
  columns_name=['宝贝id', '商家编码', '行业类目'],
@@ -1308,27 +1460,22 @@ class MysqlDatasQuery:
1308
1460
  '二级类目': 'varchar(100)',
1309
1461
  '三级类目': 'varchar(100)',
1310
1462
  }
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
1463
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1464
+ return df, {
1465
+ 'db_name': db_name,
1466
+ 'table_name': table_name,
1467
+ 'set_typ': set_typ,
1468
+ 'primary_keys': [], # 创建唯一主键
1469
+ 'check_duplicate': False, # 检查重复数据
1470
+ 'duplicate_columns': [], # 指定排重的组合键
1471
+ 'update_on_duplicate': True, # 更新旧数据
1472
+ 'allow_null': False, # 允许插入空值
1473
+ 'partition_by': None, # 分表方式
1474
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1475
+ 'indexes': [], # 普通索引列
1476
+ 'transaction_mode': 'batch', # 事务模式
1477
+ 'unique_keys': [['宝贝id']], # 唯一约束列表
1478
+ }
1332
1479
 
1333
1480
  @try_except
1334
1481
  def idbm(self, db_name='聚合数据', table_name='商品id编码表'):
@@ -1342,7 +1489,7 @@ class MysqlDatasQuery:
1342
1489
  '三级类目': 1,
1343
1490
  '更新时间': 1
1344
1491
  }
1345
- df = self.download.data_to_df(
1492
+ df = self.download_manager.data_to_df(
1346
1493
  db_name='属性设置3',
1347
1494
  table_name='商品sku属性',
1348
1495
  start_date='2024-11-17',
@@ -1362,83 +1509,25 @@ class MysqlDatasQuery:
1362
1509
  '三级类目': 'varchar(100)',
1363
1510
  '更新时间': 'timestamp'
1364
1511
  }
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)',
1512
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1513
+ return df, {
1514
+ 'db_name': db_name,
1515
+ 'table_name': table_name,
1516
+ 'set_typ': set_typ,
1517
+ 'primary_keys': [], # 创建唯一主键
1518
+ 'check_duplicate': False, # 检查重复数据
1519
+ 'duplicate_columns': [], # 指定排重的组合键
1520
+ 'update_on_duplicate': True, # 更新旧数据
1521
+ 'allow_null': False, # 允许插入空值
1522
+ 'partition_by': None, # 分表方式
1523
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1524
+ 'indexes': [], # 普通索引列
1525
+ 'transaction_mode': 'batch', # 事务模式
1526
+ 'unique_keys': [['宝贝id']], # 唯一约束列表
1418
1527
  }
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
1528
 
1441
1529
  @try_except
1530
+ @upload_data_decorator()
1442
1531
  def sp_picture(self, db_name='聚合数据', table_name='商品id图片对照表'):
1443
1532
  """ """
1444
1533
  projection = {
@@ -1450,7 +1539,7 @@ class MysqlDatasQuery:
1450
1539
  'sku地址': 1,
1451
1540
  '更新时间': 1
1452
1541
  }
1453
- df = self.download.data_to_df(
1542
+ df = self.download_manager.data_to_df(
1454
1543
  db_name='属性设置3',
1455
1544
  table_name='商品sku属性',
1456
1545
  start_date='2024-11-17',
@@ -1471,40 +1560,35 @@ class MysqlDatasQuery:
1471
1560
  'sku地址': 'varchar(255)',
1472
1561
  '更新时间': 'timestamp'
1473
1562
  }
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
1563
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1564
+ return df, {
1565
+ 'db_name': db_name,
1566
+ 'table_name': table_name,
1567
+ 'set_typ': set_typ,
1568
+ 'primary_keys': [], # 创建唯一主键
1569
+ 'check_duplicate': False, # 检查重复数据
1570
+ 'duplicate_columns': [], # 指定排重的组合键
1571
+ 'update_on_duplicate': True, # 更新旧数据
1572
+ 'allow_null': False, # 允许插入空值
1573
+ 'partition_by': None, # 分表方式
1574
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1575
+ 'indexes': [], # 普通索引列
1576
+ 'transaction_mode': 'batch', # 事务模式
1577
+ 'unique_keys': [['sku_id']], # 唯一约束列表
1578
+ }
1496
1579
 
1580
+ @upload_data_decorator()
1497
1581
  def item_up(self, db_name='聚合数据', table_name='淘宝店铺货品'):
1498
1582
  start_date, end_date = self.months_data(num=self.months)
1499
1583
  projection = {}
1500
- df_set = self.download.data_to_df(
1584
+ df_set = self.download_manager.data_to_df(
1501
1585
  db_name='属性设置3',
1502
1586
  table_name=f'货品年份基准',
1503
1587
  start_date=start_date,
1504
1588
  end_date=end_date,
1505
1589
  projection={'商品id':1, '上市年份':1},
1506
1590
  )
1507
- df = self.download.data_to_df(
1591
+ df = self.download_manager.data_to_df(
1508
1592
  db_name='市场数据3',
1509
1593
  table_name=f'淘宝店铺数据',
1510
1594
  start_date=start_date,
@@ -1526,7 +1610,7 @@ class MysqlDatasQuery:
1526
1610
  df['上市年份'] = df['商品id'].apply(lambda x: check_year(x))
1527
1611
  p = df.pop('上市年份')
1528
1612
  df.insert(loc=5, column='上市年份', value=p)
1529
- logger.info(f'正在更新: mysql ({host}:{port}) {db_name}/{table_name}')
1613
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1530
1614
  set_typ = {
1531
1615
  '日期': 'date',
1532
1616
  '店铺id': 'bigint',
@@ -1542,26 +1626,31 @@ class MysqlDatasQuery:
1542
1626
  '更新时间': 'timestamp',
1543
1627
  '上市年份': 'varchar(50)',
1544
1628
  }
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
- )
1629
+ return df, {
1630
+ 'db_name': db_name,
1631
+ 'table_name': table_name,
1632
+ 'set_typ': set_typ,
1633
+ 'primary_keys': [], # 创建唯一主键
1634
+ 'check_duplicate': False, # 检查重复数据
1635
+ 'duplicate_columns': [], # 指定排重的组合键
1636
+ 'update_on_duplicate': True, # 更新旧数据
1637
+ 'allow_null': False, # 允许插入空值
1638
+ 'partition_by': None, # 分表方式
1639
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1640
+ 'indexes': [], # 普通索引列
1641
+ 'transaction_mode': 'batch', # 事务模式
1642
+ 'unique_keys': [['日期', '店铺id', '商品id']], # 唯一约束列表
1643
+ }
1556
1644
 
1557
1645
 
1646
+ @upload_data_decorator()
1558
1647
  def spph(self, db_name='聚合数据', table_name='天猫_商品排行'):
1559
1648
  """ """
1560
1649
  start_date, end_date = self.months_data(num=self.months)
1561
1650
  projection = {}
1562
1651
  __res = []
1563
1652
  for year in range(2024, datetime.datetime.today().year+1):
1564
- df = self.download.data_to_df(
1653
+ df = self.download_manager.data_to_df(
1565
1654
  db_name='生意参谋3',
1566
1655
  table_name=f'商品排行_{year}',
1567
1656
  start_date=start_date,
@@ -1572,7 +1661,7 @@ class MysqlDatasQuery:
1572
1661
  df = pd.concat(__res, ignore_index=True)
1573
1662
 
1574
1663
  projection = {}
1575
- df_set = self.download.data_to_df(
1664
+ df_set = self.download_manager.data_to_df(
1576
1665
  db_name='属性设置3',
1577
1666
  table_name=f'货品年份基准',
1578
1667
  start_date=start_date,
@@ -1663,22 +1752,25 @@ class MysqlDatasQuery:
1663
1752
  '更新时间': 'timestamp',
1664
1753
  '上市年份': 'varchar(100)',
1665
1754
  }
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
- )
1755
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1756
+ return df, {
1757
+ 'db_name': db_name,
1758
+ 'table_name': table_name,
1759
+ 'set_typ': set_typ,
1760
+ 'primary_keys': [], # 创建唯一主键
1761
+ 'check_duplicate': False, # 检查重复数据
1762
+ 'duplicate_columns': [], # 指定排重的组合键
1763
+ 'update_on_duplicate': True, # 更新旧数据
1764
+ 'allow_null': False, # 允许插入空值
1765
+ 'partition_by': None, # 分表方式
1766
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1767
+ 'indexes': [], # 普通索引列
1768
+ 'transaction_mode': 'batch', # 事务模式
1769
+ 'unique_keys': [['日期', '店铺名称', '商品id']], # 唯一约束列表
1770
+ }
1680
1771
 
1681
1772
  # @try_except
1773
+ @upload_data_decorator()
1682
1774
  def dplyd(self, db_name='聚合数据', table_name='店铺流量来源构成'):
1683
1775
  """ 新旧版取的字段是一样的 """
1684
1776
  start_date, end_date = self.months_data(num=self.months)
@@ -1701,7 +1793,7 @@ class MysqlDatasQuery:
1701
1793
  }
1702
1794
  __res = []
1703
1795
  for year in range(2024, datetime.datetime.today().year+1):
1704
- df = self.download.data_to_df(
1796
+ df = self.download_manager.data_to_df(
1705
1797
  db_name='生意参谋3',
1706
1798
  table_name=f'店铺流量来源构成_{year}',
1707
1799
  start_date=start_date,
@@ -1769,27 +1861,28 @@ class MysqlDatasQuery:
1769
1861
  '二级来源索引': 'smallint',
1770
1862
  '三级来源索引': 'smallint',
1771
1863
  }
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
1864
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '': table_name})
1865
+ return df, {
1866
+ 'db_name': db_name,
1867
+ 'table_name': table_name,
1868
+ 'set_typ': set_typ,
1869
+ 'primary_keys': [], # 创建唯一主键
1870
+ 'check_duplicate': False, # 检查重复数据
1871
+ 'duplicate_columns': [], # 指定排重的组合键
1872
+ 'update_on_duplicate': True, # 更新旧数据
1873
+ 'allow_null': False, # 允许插入空值
1874
+ 'partition_by': None, # 分表方式
1875
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1876
+ 'indexes': [], # 普通索引列
1877
+ 'transaction_mode': 'batch', # 事务模式
1878
+ 'unique_keys': [['日期', '店铺名称', '类别', '来源构成', '一级来源', '二级来源', '三级来源']], # 唯一约束列表
1879
+ }
1788
1880
 
1789
1881
  @try_except
1882
+ @upload_data_decorator()
1790
1883
  def sp_cost(self, db_name='聚合数据', table_name='商品成本'):
1791
1884
  """ 电商定价 """
1792
- data_values = self.download.columns_to_list(
1885
+ data_values = self.download_manager.columns_to_list(
1793
1886
  db_name='属性设置3',
1794
1887
  table_name='电商定价',
1795
1888
  columns_name=['日期', '款号', '年份季节', '吊牌价', '商家平台', '成本价', '天猫页面价', '天猫中促价'],
@@ -1806,31 +1899,25 @@ class MysqlDatasQuery:
1806
1899
  '天猫页面价': 'decimal(10,2)',
1807
1900
  '天猫中促价': 'decimal(10,2)',
1808
1901
  }
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
1902
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
1903
+ return df, {
1904
+ 'db_name': db_name,
1905
+ 'table_name': table_name,
1906
+ 'set_typ': set_typ,
1907
+ 'primary_keys': [], # 创建唯一主键
1908
+ 'check_duplicate': False, # 检查重复数据
1909
+ 'duplicate_columns': [], # 指定排重的组合键
1910
+ 'update_on_duplicate': True, # 更新旧数据
1911
+ 'allow_null': False, # 允许插入空值
1912
+ 'partition_by': None, # 分表方式
1913
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
1914
+ 'indexes': [], # 普通索引列
1915
+ 'transaction_mode': 'batch', # 事务模式
1916
+ 'unique_keys': [['款号']], # 唯一约束列表
1917
+ }
1832
1918
 
1833
1919
  # @try_except
1920
+ @upload_data_decorator()
1834
1921
  def jdjzt(self, db_name='聚合数据', table_name='京东_京准通'):
1835
1922
  start_date, end_date = self.months_data(num=self.months)
1836
1923
  projection = {
@@ -1852,7 +1939,7 @@ class MysqlDatasQuery:
1852
1939
  }
1853
1940
  __res = []
1854
1941
  for year in range(2024, datetime.datetime.today().year + 1):
1855
- df = self.download.data_to_df(
1942
+ df = self.download_manager.data_to_df(
1856
1943
  db_name='京东数据3',
1857
1944
  table_name=f'推广数据_京准通_{year}',
1858
1945
  start_date=start_date,
@@ -1862,7 +1949,7 @@ class MysqlDatasQuery:
1862
1949
  __res.append(df)
1863
1950
  # 新增加自营店数据 2025-03-19
1864
1951
  for year in range(2025, datetime.datetime.today().year + 1):
1865
- df = self.download.data_to_df(
1952
+ df = self.download_manager.data_to_df(
1866
1953
  db_name='京东数据3',
1867
1954
  table_name=f'推广数据_京准通_自营店_{year}',
1868
1955
  start_date=start_date,
@@ -1889,7 +1976,7 @@ class MysqlDatasQuery:
1889
1976
  'sku_id': 1,
1890
1977
  'spu_id': 1,
1891
1978
  }
1892
- df_sku = self.download.data_to_df(
1979
+ df_sku = self.download_manager.data_to_df(
1893
1980
  db_name='属性设置3',
1894
1981
  table_name='京东商品属性',
1895
1982
  start_date=start_date,
@@ -1901,15 +1988,6 @@ class MysqlDatasQuery:
1901
1988
  df.pop('sku_id') # 删除聚合后合并进来的 sku id,实际使用 跟单sku_id
1902
1989
  p = df.pop('spu_id')
1903
1990
  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
1991
  set_typ = {
1914
1992
  '日期': 'date',
1915
1993
  '店铺名称': 'varchar(100)',
@@ -1927,23 +2005,25 @@ class MysqlDatasQuery:
1927
2005
  '直接加购数': 'int',
1928
2006
  '总加购数': 'int',
1929
2007
  }
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
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': [['日期', '店铺名称', '产品线', '触发sku_id', '跟单sku_id']], # 唯一约束列表
2023
+ }
1945
2024
 
1946
2025
  @try_except
2026
+ @upload_data_decorator()
1947
2027
  def jdqzyx(self, db_name='聚合数据', table_name='京东_京准通_全站营销'):
1948
2028
  start_date, end_date = self.months_data(num=self.months)
1949
2029
  projection = {
@@ -1959,7 +2039,7 @@ class MysqlDatasQuery:
1959
2039
  '核心位置展现量': 1,
1960
2040
  '核心位置点击量': 1,
1961
2041
  }
1962
- df = self.download.data_to_df(
2042
+ df = self.download_manager.data_to_df(
1963
2043
  db_name='京东数据3',
1964
2044
  table_name='推广数据_全站营销', # 暂缺
1965
2045
  start_date=start_date,
@@ -1967,7 +2047,7 @@ class MysqlDatasQuery:
1967
2047
  projection=projection,
1968
2048
  )
1969
2049
  if len(df) == 0:
1970
- return False
2050
+ return None, None
1971
2051
  df = df.groupby(['日期', '店铺名称', '产品线', '花费'], as_index=False).agg(
1972
2052
  **{
1973
2053
  '全站投产比': ('全站投产比', np.max),
@@ -1993,23 +2073,25 @@ class MysqlDatasQuery:
1993
2073
  '核心位置展现量': 'int',
1994
2074
  '核心位置点击量': 'int',
1995
2075
  }
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
2076
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2077
+ return df, {
2078
+ 'db_name': db_name,
2079
+ 'table_name': table_name,
2080
+ 'set_typ': set_typ,
2081
+ 'primary_keys': [], # 创建唯一主键
2082
+ 'check_duplicate': False, # 检查重复数据
2083
+ 'duplicate_columns': [], # 指定排重的组合键
2084
+ 'update_on_duplicate': True, # 更新旧数据
2085
+ 'allow_null': False, # 允许插入空值
2086
+ 'partition_by': None, # 分表方式
2087
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
2088
+ 'indexes': [], # 普通索引列
2089
+ 'transaction_mode': 'batch', # 事务模式
2090
+ 'unique_keys': [['日期', '店铺名称', '产品线']], # 唯一约束列表
2091
+ }
2011
2092
 
2012
2093
  @try_except
2094
+ @upload_data_decorator()
2013
2095
  def jd_gjc(self, db_name='聚合数据', table_name='京东_关键词报表'):
2014
2096
  start_date, end_date = self.months_data(num=self.months)
2015
2097
  projection = {
@@ -2036,7 +2118,7 @@ class MysqlDatasQuery:
2036
2118
  }
2037
2119
  __res = []
2038
2120
  for year in range(2024, datetime.datetime.today().year + 1):
2039
- df = self.download.data_to_df(
2121
+ df = self.download_manager.data_to_df(
2040
2122
  db_name='京东数据3',
2041
2123
  table_name=f'推广数据_关键词报表_{year}',
2042
2124
  start_date=start_date,
@@ -2091,23 +2173,25 @@ class MysqlDatasQuery:
2091
2173
  'k_是否品牌词': 'varchar(100)',
2092
2174
  's_是否品牌词': 'varchar(100)',
2093
2175
  }
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
2176
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2177
+ return df, {
2178
+ 'db_name': db_name,
2179
+ 'table_name': table_name,
2180
+ 'set_typ': set_typ,
2181
+ 'primary_keys': [], # 创建唯一主键
2182
+ 'check_duplicate': False, # 检查重复数据
2183
+ 'duplicate_columns': [], # 指定排重的组合键
2184
+ 'update_on_duplicate': True, # 更新旧数据
2185
+ 'allow_null': False, # 允许插入空值
2186
+ 'partition_by': None, # 分表方式
2187
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
2188
+ 'indexes': [], # 普通索引列
2189
+ 'transaction_mode': 'batch', # 事务模式
2190
+ 'unique_keys': [['日期', '产品线', '计划id', '搜索词', '关键词']], # 唯一约束列表
2191
+ }
2109
2192
 
2110
2193
  @try_except
2194
+ @upload_data_decorator()
2111
2195
  def sku_sales(self, db_name='聚合数据', table_name='京东_sku_商品明细'):
2112
2196
  start_date, end_date = self.months_data(num=self.months)
2113
2197
  projection = {
@@ -2125,7 +2209,7 @@ class MysqlDatasQuery:
2125
2209
  }
2126
2210
  __res = []
2127
2211
  for year in range(2024, datetime.datetime.today().year + 1):
2128
- df = self.download.data_to_df(
2212
+ df = self.download_manager.data_to_df(
2129
2213
  db_name='京东数据3',
2130
2214
  table_name=f'京东商智_sku_商品明细_{year}',
2131
2215
  start_date=start_date,
@@ -2146,14 +2230,6 @@ class MysqlDatasQuery:
2146
2230
  idx = df.groupby(['日期', '店铺名称', '商品id', '货号', '访客数', '成交客户数', '加购商品件数', '加购人数'])['更新时间'].idxmax()
2147
2231
  df = df.loc[idx]
2148
2232
  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
2233
  set_typ = {
2158
2234
  '日期': 'date',
2159
2235
  '店铺名称': 'varchar(100)',
@@ -2167,23 +2243,25 @@ class MysqlDatasQuery:
2167
2243
  '成交金额': 'decimal(10,2)',
2168
2244
  'sku_id': 'varchar(100)',
2169
2245
  }
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
2246
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2247
+ return df, {
2248
+ 'db_name': db_name,
2249
+ 'table_name': table_name,
2250
+ 'set_typ': set_typ,
2251
+ 'primary_keys': [], # 创建唯一主键
2252
+ 'check_duplicate': False, # 检查重复数据
2253
+ 'duplicate_columns': [], # 指定排重的组合键
2254
+ 'update_on_duplicate': True, # 更新旧数据
2255
+ 'allow_null': False, # 允许插入空值
2256
+ 'partition_by': None, # 分表方式
2257
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
2258
+ 'indexes': [], # 普通索引列
2259
+ 'transaction_mode': 'batch', # 事务模式
2260
+ 'unique_keys': [['日期', '店铺名称', '商品id']], # 唯一约束列表
2261
+ }
2185
2262
 
2186
2263
  @try_except
2264
+ @upload_data_decorator()
2187
2265
  def spu_sales(self, db_name='聚合数据', table_name='京东_spu_商品明细'):
2188
2266
  start_date, end_date = self.months_data(num=self.months)
2189
2267
  projection = {
@@ -2201,7 +2279,7 @@ class MysqlDatasQuery:
2201
2279
  }
2202
2280
  __res = []
2203
2281
  for year in range(2024, datetime.datetime.today().year + 1):
2204
- df = self.download.data_to_df(
2282
+ df = self.download_manager.data_to_df(
2205
2283
  db_name='京东数据3',
2206
2284
  table_name=f'京东商智_spu_商品明细_{year}',
2207
2285
  start_date=start_date,
@@ -2235,21 +2313,22 @@ class MysqlDatasQuery:
2235
2313
  '成交金额': 'decimal(10,2)',
2236
2314
  'spu_id': 'varchar(100)',
2237
2315
  }
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
2316
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2317
+ return df, {
2318
+ 'db_name': db_name,
2319
+ 'table_name': table_name,
2320
+ 'set_typ': set_typ,
2321
+ 'primary_keys': [], # 创建唯一主键
2322
+ 'check_duplicate': False, # 检查重复数据
2323
+ 'duplicate_columns': [], # 指定排重的组合键
2324
+ 'update_on_duplicate': True, # 更新旧数据
2325
+ 'allow_null': False, # 允许插入空值
2326
+ 'partition_by': None, # 分表方式
2327
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
2328
+ 'indexes': [], # 普通索引列
2329
+ 'transaction_mode': 'batch', # 事务模式
2330
+ 'unique_keys': [['日期', '店铺名称', '商品id']], # 唯一约束列表
2331
+ }
2253
2332
 
2254
2333
  @staticmethod
2255
2334
  def months_data(num=0, end_date=None):
@@ -2261,6 +2340,7 @@ class MysqlDatasQuery:
2261
2340
  return pd.to_datetime(start_date), pd.to_datetime(end_date)
2262
2341
 
2263
2342
  @try_except
2343
+ @upload_data_decorator()
2264
2344
  def se_search(self, db_name='聚合数据', table_name='天猫店铺来源_手淘搜索'):
2265
2345
  start_date, end_date = self.months_data(num=self.months)
2266
2346
  projection = {
@@ -2281,7 +2361,7 @@ class MysqlDatasQuery:
2281
2361
  }
2282
2362
  __res = []
2283
2363
  for year in range(2024, datetime.datetime.today().year+1):
2284
- df = self.download.data_to_df(
2364
+ df = self.download_manager.data_to_df(
2285
2365
  db_name='生意参谋3',
2286
2366
  table_name=f'手淘搜索_本店引流词_{year}',
2287
2367
  start_date=start_date,
@@ -2290,19 +2370,6 @@ class MysqlDatasQuery:
2290
2370
  )
2291
2371
  __res.append(df)
2292
2372
  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
2373
  idx = df.groupby(['日期', '店铺名称', '词类型', '搜索词'])['更新时间'].idxmax()
2307
2374
  df = df.loc[idx]
2308
2375
  df = df[['日期', '店铺名称', '词类型', '搜索词', '访客数', '加购人数', '支付金额', '支付转化率', '支付买家数', '客单价', 'uv价值']]
@@ -2320,65 +2387,33 @@ class MysqlDatasQuery:
2320
2387
  '客单价': 'decimal(10,2)',
2321
2388
  'uv价值': 'decimal(10,2)',
2322
2389
  }
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
2390
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2391
+ return df, {
2392
+ 'db_name': db_name,
2393
+ 'table_name': table_name,
2394
+ 'set_typ': set_typ,
2395
+ 'primary_keys': [], # 创建唯一主键
2396
+ 'check_duplicate': False, # 检查重复数据
2397
+ 'duplicate_columns': [], # 指定排重的组合键
2398
+ 'update_on_duplicate': True, # 更新旧数据
2399
+ 'allow_null': False, # 允许插入空值
2400
+ 'partition_by': None, # 分表方式
2401
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
2402
+ 'indexes': [], # 普通索引列
2403
+ 'transaction_mode': 'batch', # 事务模式
2404
+ 'unique_keys': [['日期', '店铺名称', '词类型', '搜索词']], # 唯一约束列表
2405
+ }
2338
2406
 
2339
2407
  @try_except
2408
+ @upload_data_decorator()
2340
2409
  def zb_ccfx(self, db_name='聚合数据', table_name='生意参谋_直播场次分析'):
2341
2410
  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(
2411
+ df = self.download_manager.data_to_df(
2377
2412
  db_name='生意参谋3',
2378
2413
  table_name='直播分场次效果',
2379
2414
  start_date=start_date,
2380
2415
  end_date=end_date,
2381
- projection=projection,
2416
+ projection={},
2382
2417
  )
2383
2418
  df.drop_duplicates(subset=['场次id'], keep='first', inplace=True, ignore_index=True)
2384
2419
  set_typ = {
@@ -2455,9 +2490,7 @@ class MysqlDatasQuery:
2455
2490
  '封面图': 'text',
2456
2491
  '更新时间': 'timestamp',
2457
2492
  }
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}')
2493
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2461
2494
  new_dict = {
2462
2495
  '日期': '',
2463
2496
  '店铺名称': '',
@@ -2496,16 +2529,26 @@ class MysqlDatasQuery:
2496
2529
  new_dict.update(dict_data)
2497
2530
  _results.append(new_dict)
2498
2531
  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
2532
+ return _results, {
2533
+ 'db_name': db_name,
2534
+ 'table_name': table_name,
2535
+ 'set_typ': set_typ,
2536
+ 'primary_keys': ['场次id'], # 创建唯一主键
2537
+ 'check_duplicate': False, # 检查重复数据
2538
+ 'duplicate_columns': [], # 指定排重的组合键
2539
+ 'update_on_duplicate': True, # 更新旧数据
2540
+ 'allow_null': False, # 允许插入空值
2541
+ 'partition_by': None, # 分表方式
2542
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
2543
+ 'indexes': [], # 普通索引列
2544
+ 'transaction_mode': 'batch', # 事务模式
2545
+ 'unique_keys': [['场次id']], # 唯一约束列表
2546
+ }
2547
+ else:
2548
+ return None, None
2507
2549
 
2508
2550
  # @try_except
2551
+ @upload_data_decorator()
2509
2552
  def tg_by_day(self, db_name='聚合数据', table_name='多店推广场景_按日聚合'):
2510
2553
  """
2511
2554
  汇总各个店铺的推广数据,按日汇总
@@ -2535,7 +2578,7 @@ class MysqlDatasQuery:
2535
2578
  }
2536
2579
  __res = []
2537
2580
  for year in range(2024, datetime.datetime.today().year + 1):
2538
- df_tm = self.download.data_to_df(
2581
+ df_tm = self.download_manager.data_to_df(
2539
2582
  db_name='推广数据2',
2540
2583
  table_name=f'营销场景报表_{year}',
2541
2584
  start_date=start_date,
@@ -2560,7 +2603,7 @@ class MysqlDatasQuery:
2560
2603
  # 奥莱店
2561
2604
  __res = []
2562
2605
  for year in range(2024, datetime.datetime.today().year + 1):
2563
- df_al = self.download.data_to_df(
2606
+ df_al = self.download_manager.data_to_df(
2564
2607
  db_name='推广数据_奥莱店',
2565
2608
  table_name=f'营销场景报表_{year}',
2566
2609
  start_date=start_date,
@@ -2586,7 +2629,7 @@ class MysqlDatasQuery:
2586
2629
  # sj圣积
2587
2630
  __res = []
2588
2631
  for year in range(2025, datetime.datetime.today().year + 1):
2589
- df_sj = self.download.data_to_df(
2632
+ df_sj = self.download_manager.data_to_df(
2590
2633
  db_name='推广数据_圣积天猫店',
2591
2634
  table_name=f'营销场景报表_{year}',
2592
2635
  start_date=start_date,
@@ -2612,7 +2655,7 @@ class MysqlDatasQuery:
2612
2655
  # 淘宝店
2613
2656
  __res = []
2614
2657
  for year in range(2024, datetime.datetime.today().year + 1):
2615
- df_tb = self.download.data_to_df(
2658
+ df_tb = self.download_manager.data_to_df(
2616
2659
  db_name='推广数据_淘宝店',
2617
2660
  table_name=f'营销场景报表_{year}',
2618
2661
  start_date=start_date,
@@ -2651,7 +2694,7 @@ class MysqlDatasQuery:
2651
2694
  }
2652
2695
  __res = []
2653
2696
  for year in range(2024, datetime.datetime.today().year + 1):
2654
- df_tb_qzt = self.download.data_to_df(
2697
+ df_tb_qzt = self.download_manager.data_to_df(
2655
2698
  db_name='推广数据_淘宝店',
2656
2699
  table_name=f'全站推广报表_{year}',
2657
2700
  start_date=start_date,
@@ -2701,7 +2744,7 @@ class MysqlDatasQuery:
2701
2744
  }
2702
2745
  __res = []
2703
2746
  for year in range(2024, datetime.datetime.today().year + 1):
2704
- df_tm_pxb = self.download.data_to_df(
2747
+ df_tm_pxb = self.download_manager.data_to_df(
2705
2748
  db_name='推广数据2',
2706
2749
  table_name=f'品销宝_{year}',
2707
2750
  start_date=start_date,
@@ -2741,7 +2784,7 @@ class MysqlDatasQuery:
2741
2784
  }
2742
2785
  __res = []
2743
2786
  for year in range(2024, datetime.datetime.today().year + 1):
2744
- df_tm_living = self.download.data_to_df(
2787
+ df_tm_living = self.download_manager.data_to_df(
2745
2788
  db_name='推广数据2',
2746
2789
  table_name=f'超级直播报表_人群_{year}',
2747
2790
  start_date=start_date,
@@ -2783,7 +2826,7 @@ class MysqlDatasQuery:
2783
2826
  }
2784
2827
  __res = []
2785
2828
  for year in range(2024, datetime.datetime.today().year + 1):
2786
- df_jd = self.download.data_to_df(
2829
+ df_jd = self.download_manager.data_to_df(
2787
2830
  db_name='京东数据3',
2788
2831
  table_name=f'推广数据_京准通_{year}',
2789
2832
  start_date=start_date,
@@ -2821,7 +2864,7 @@ class MysqlDatasQuery:
2821
2864
  '核心位置点击量': 1,
2822
2865
  '店铺名称': 1,
2823
2866
  }
2824
- df_jd_qzyx = self.download.data_to_df(
2867
+ df_jd_qzyx = self.download_manager.data_to_df(
2825
2868
  db_name='京东数据3',
2826
2869
  table_name='推广数据_全站营销',
2827
2870
  start_date=start_date,
@@ -2862,7 +2905,7 @@ class MysqlDatasQuery:
2862
2905
  }
2863
2906
  __res = []
2864
2907
  for year in range(2025, datetime.datetime.today().year + 1):
2865
- df_jd_ziying = self.download.data_to_df(
2908
+ df_jd_ziying = self.download_manager.data_to_df(
2866
2909
  db_name='京东数据3',
2867
2910
  table_name=f'推广数据_京准通_自营店_{year}',
2868
2911
  start_date=start_date,
@@ -2952,25 +2995,25 @@ class MysqlDatasQuery:
2952
2995
  '成交笔数': 'int',
2953
2996
  '成交金额': 'decimal(12,2)',
2954
2997
  }
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
2998
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
2999
+ return df, {
3000
+ 'db_name': db_name,
3001
+ 'table_name': table_name,
3002
+ 'set_typ': set_typ,
3003
+ 'primary_keys': [], # 创建唯一主键
3004
+ 'check_duplicate': False, # 检查重复数据
3005
+ 'duplicate_columns': [], # 指定排重的组合键
3006
+ 'update_on_duplicate': True, # 更新旧数据
3007
+ 'allow_null': False, # 允许插入空值
3008
+ 'partition_by': None, # 分表方式
3009
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
3010
+ 'indexes': [], # 普通索引列
3011
+ 'transaction_mode': 'batch', # 事务模式
3012
+ 'unique_keys': [['日期', '店铺名称', '营销场景']], # 唯一约束列表
3013
+ }
2972
3014
 
2973
3015
  @try_except
3016
+ @upload_data_decorator()
2974
3017
  def aikucun_bd_spu(self, db_name='聚合数据', table_name='爱库存_商品spu榜单'):
2975
3018
  start_date, end_date = self.months_data(num=self.months)
2976
3019
  projection = {
@@ -3011,7 +3054,7 @@ class MysqlDatasQuery:
3011
3054
  '更新时间': 1,
3012
3055
  }
3013
3056
  projection = {}
3014
- df = self.download.data_to_df(
3057
+ df = self.download_manager.data_to_df(
3015
3058
  db_name='爱库存2',
3016
3059
  table_name='spu榜单',
3017
3060
  start_date=start_date,
@@ -3043,26 +3086,28 @@ class MysqlDatasQuery:
3043
3086
  '数据更新时间': 'timestamp',
3044
3087
  '更新时间': 'timestamp',
3045
3088
  }
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
3089
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
3090
+ return df, {
3091
+ 'db_name': db_name,
3092
+ 'table_name': table_name,
3093
+ 'set_typ': set_typ,
3094
+ 'primary_keys': [], # 创建唯一主键
3095
+ 'check_duplicate': False, # 检查重复数据
3096
+ 'duplicate_columns': [], # 指定排重的组合键
3097
+ 'update_on_duplicate': True, # 更新旧数据
3098
+ 'allow_null': False, # 允许插入空值
3099
+ 'partition_by': None, # 分表方式
3100
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
3101
+ 'indexes': [], # 普通索引列
3102
+ 'transaction_mode': 'batch', # 事务模式
3103
+ 'unique_keys': [['日期', '店铺名称', '商品款号', 'spuid']], # 唯一约束列表
3104
+ }
3061
3105
 
3106
+ @upload_data_decorator()
3062
3107
  def deeplink(self, db_name='聚合数据', table_name='达摩盘_deeplink人群洞察'):
3063
3108
  start_date, end_date = self.months_data(num=self.months)
3064
3109
  projection = {}
3065
- df = self.download.data_to_df(
3110
+ df = self.download_manager.data_to_df(
3066
3111
  db_name='达摩盘3',
3067
3112
  table_name='店铺deeplink人群洞察',
3068
3113
  start_date=start_date,
@@ -3070,8 +3115,6 @@ class MysqlDatasQuery:
3070
3115
  projection=projection,
3071
3116
  )
3072
3117
  df.drop_duplicates(subset=['日期', '人群类型', '店铺名称', '人群规模', '广告投入金额'], keep='last', inplace=True, ignore_index=True)
3073
- if not self.update_service:
3074
- return
3075
3118
  set_typ = {
3076
3119
  '日期': 'date',
3077
3120
  '人群类型': 'varchar(100)',
@@ -3092,23 +3135,25 @@ class MysqlDatasQuery:
3092
3135
  '长周期成交价值': 'decimal(13, 2)',
3093
3136
  '达摩盘id': 'int',
3094
3137
  }
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
3138
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
3139
+ return df, {
3140
+ 'db_name': db_name,
3141
+ 'table_name': table_name,
3142
+ 'set_typ': set_typ,
3143
+ 'primary_keys': [], # 创建唯一主键
3144
+ 'check_duplicate': False, # 检查重复数据
3145
+ 'duplicate_columns': [], # 指定排重的组合键
3146
+ 'update_on_duplicate': True, # 更新旧数据
3147
+ 'allow_null': False, # 允许插入空值
3148
+ 'partition_by': None, # 分表方式
3149
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
3150
+ 'indexes': [], # 普通索引列
3151
+ 'transaction_mode': 'batch', # 事务模式
3152
+ 'unique_keys': [['日期', '人群类型', '店铺名称', '人群规模']], # 唯一约束列表
3153
+ }
3110
3154
 
3111
3155
  # @try_except
3156
+ @upload_data_decorator()
3112
3157
  def dmp_crowd(self, db_name='聚合数据', table_name='达摩盘_人群报表'):
3113
3158
  start_date, end_date = self.months_data(num=self.months)
3114
3159
  projection = {
@@ -3120,7 +3165,7 @@ class MysqlDatasQuery:
3120
3165
  '用户性别': 1,
3121
3166
  }
3122
3167
  # projection = {}
3123
- df_crowd = self.download.data_to_df(
3168
+ df_crowd = self.download_manager.data_to_df(
3124
3169
  db_name='达摩盘3',
3125
3170
  table_name='我的人群属性',
3126
3171
  start_date=start_date,
@@ -3135,7 +3180,7 @@ class MysqlDatasQuery:
3135
3180
  projection = {}
3136
3181
  __res = []
3137
3182
  for year in range(2024, datetime.datetime.today().year + 1):
3138
- df_dmp = self.download.data_to_df(
3183
+ df_dmp = self.download_manager.data_to_df(
3139
3184
  db_name='达摩盘3',
3140
3185
  table_name=f'dmp人群报表_{year}',
3141
3186
  start_date=start_date,
@@ -3201,21 +3246,22 @@ class MysqlDatasQuery:
3201
3246
  '消费能力等级': 'varchar(100)',
3202
3247
  '用户性别': 'varchar(100)',
3203
3248
  }
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
3249
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
3250
+ return df, {
3251
+ 'db_name': db_name,
3252
+ 'table_name': table_name,
3253
+ 'set_typ': set_typ,
3254
+ 'primary_keys': [], # 创建唯一主键
3255
+ 'check_duplicate': False, # 检查重复数据
3256
+ 'duplicate_columns': [], # 指定排重的组合键
3257
+ 'update_on_duplicate': True, # 更新旧数据
3258
+ 'allow_null': False, # 允许插入空值
3259
+ 'partition_by': None, # 分表方式
3260
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
3261
+ 'indexes': [], # 普通索引列
3262
+ 'transaction_mode': 'batch', # 事务模式
3263
+ 'unique_keys': [['日期', '店铺名称', '人群id', '营销渠道', '计划基础信息']], # 唯一约束列表
3264
+ }
3219
3265
 
3220
3266
  @try_except
3221
3267
  def ret_keyword(self, keyword, as_file=False):
@@ -3513,110 +3559,7 @@ class MysqlDatasQuery:
3513
3559
  return result
3514
3560
 
3515
3561
  # @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
3562
+ @upload_data_decorator()
3620
3563
  def performance_concat(self, db_name, table_name, bb_tg=True):
3621
3564
  tg = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '天猫汇总表调用'][0]
3622
3565
  zb = [item['数据主体'] for item in self.pf_datas if item['集合名称'] == '天猫_超级直播'][0]
@@ -3697,92 +3640,23 @@ class MysqlDatasQuery:
3697
3640
  '直接成交金额': 'decimal(12,2)',
3698
3641
  '自然流量曝光量': 'int',
3699
3642
  }
3700
- if not self.update_service:
3701
- return
3702
3643
  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
3644
+ logger.info('正在更新数据库', {'主机': f'{host}:{port}', '库': db_name, '表': table_name})
3645
+ return df, {
3646
+ 'db_name': db_name,
3647
+ 'table_name': table_name,
3648
+ 'set_typ': set_typ,
3649
+ 'primary_keys': [], # 创建唯一主键
3650
+ 'check_duplicate': False, # 检查重复数据
3651
+ 'duplicate_columns': [], # 指定排重的组合键
3652
+ 'update_on_duplicate': True, # 更新旧数据
3653
+ 'allow_null': False, # 允许插入空值
3654
+ 'partition_by': None, # 分表方式
3655
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
3656
+ 'indexes': [], # 普通索引列
3657
+ 'transaction_mode': 'batch', # 事务模式
3658
+ 'unique_keys': [['日期', '店铺名称', '推广渠道', '营销场景', '商品id']], # 唯一约束列表
3659
+ }
3786
3660
 
3787
3661
 
3788
3662
  def get_day_of_month(num):
@@ -3798,6 +3672,7 @@ def get_day_of_month(num):
3798
3672
  return _firstDay, _lastDay
3799
3673
 
3800
3674
 
3675
+ @upload_data_decorator()
3801
3676
  def date_table():
3802
3677
  """
3803
3678
  生成 pbix 使用的日期表
@@ -3854,7 +3729,6 @@ def date_table():
3854
3729
  df = df.reset_index(drop=False)
3855
3730
  df.rename(columns={'index': 'id'}, inplace=True)
3856
3731
  df['id'] = df['id'].apply(lambda x: x + 1)
3857
-
3858
3732
  set_typ = {
3859
3733
  '日期': 'date',
3860
3734
  '年': 'varchar(50)',
@@ -3869,23 +3743,32 @@ def date_table():
3869
3743
  '索引': 'int',
3870
3744
  '月索引': 'int',
3871
3745
  }
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
- )
3746
+
3747
+ return df, {
3748
+ 'db_name': '聚合数据',
3749
+ 'table_name': '日期表',
3750
+ 'set_typ': set_typ,
3751
+ 'primary_keys': [], # 创建唯一主键
3752
+ 'check_duplicate': False, # 检查重复数据
3753
+ 'duplicate_columns': [], # 指定排重的组合键
3754
+ 'update_on_duplicate': True, # 更新旧数据
3755
+ 'allow_null': False, # 允许插入空值
3756
+ 'partition_by': None, # 分表方式
3757
+ 'partition_date_column': '日期', # 用于分表的日期列名,默认为'日期'
3758
+ 'indexes': [], # 普通索引列
3759
+ 'transaction_mode': 'batch', # 事务模式
3760
+ 'unique_keys': [['日期']], # 唯一约束列表
3761
+ }
3880
3762
 
3881
3763
 
3882
- def query1(months=1, less_dict=[]):
3764
+ def query1(months=1, less_dict=None, download_manager=None):
3765
+ if less_dict is None:
3766
+ less_dict = []
3883
3767
  if months == 0:
3884
- logger.info(f'months 不建议为 0 ')
3768
+ logger.info('months 不建议为 0')
3885
3769
  return
3886
- sdq = MysqlDatasQuery() # 实例化数据处理类
3770
+ sdq = MysqlDatasQuery(download_manager=download_manager) # 实例化数据处理类
3887
3771
  sdq.months = months # 设置数据周期, 1 表示近 2 个月
3888
- sdq.update_service = True # 调试时加,true: 将数据写入 mysql 服务器
3889
3772
 
3890
3773
  # 依赖表 -- >>
3891
3774
  sdq.tg_wxt(db_name='聚合数据', table_name='天猫_主体报表')
@@ -3907,19 +3790,17 @@ def query1(months=1, less_dict=[]):
3907
3790
  sdq.spu_sales(db_name='聚合数据', table_name='京东_spu_商品明细')
3908
3791
  sdq.zb_ccfx(db_name='聚合数据', table_name='生意参谋_直播场次分析')
3909
3792
  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
3793
  sdq.performance_concat(bb_tg=False, db_name='聚合数据', table_name='天猫_推广汇总') # _推广商品销售
3914
3794
 
3915
3795
 
3916
- def query2(months=1, less_dict=[]):
3796
+ def query2(months=1, less_dict=None, download_manager=None):
3797
+ if less_dict is None:
3798
+ less_dict = []
3917
3799
  if months == 0:
3918
- logger.info(f'months 不建议为 0 ')
3800
+ logger.info('months 不建议为 0')
3919
3801
  return
3920
- sdq = MysqlDatasQuery() # 实例化数据处理类
3802
+ sdq = MysqlDatasQuery(download_manager=download_manager) # 实例化数据处理类
3921
3803
  sdq.months = months # 设置数据周期, 1 表示近 2 个月
3922
- sdq.update_service = True # 调试时加,true: 将数据写入 mysql 服务器
3923
3804
  sdq.dplyd(db_name='聚合数据', table_name='店铺流量来源构成')
3924
3805
  sdq.tg_rqbb(db_name='聚合数据', table_name='天猫_人群报表')
3925
3806
  sdq.tg_gjc(db_name='聚合数据', table_name='天猫_关键词报表')
@@ -3930,102 +3811,35 @@ def query2(months=1, less_dict=[]):
3930
3811
  sdq.deeplink(db_name='聚合数据', table_name='达摩盘_deeplink人群洞察')
3931
3812
 
3932
3813
 
3933
- def query3(months=1, less_dict=[]):
3814
+ def query3(months=1, less_dict=None, download_manager=None):
3815
+ if less_dict is None:
3816
+ less_dict = []
3934
3817
  if months == 0:
3935
- logger.info(f'months 不建议为 0 ')
3818
+ logger.info('months 不建议为 0')
3936
3819
  return
3937
- sdq = MysqlDatasQuery() # 实例化数据处理类
3820
+ sdq = MysqlDatasQuery(download_manager=download_manager) # 实例化数据处理类
3938
3821
  sdq.months = months # 设置数据周期, 1 表示近 2 个月
3939
- sdq.update_service = True # 调试时加,true: 将数据写入 mysql 服务器
3940
3822
  sdq.spph(db_name='聚合数据', table_name='天猫_商品排行')
3941
3823
 
3942
3824
 
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
3825
  def main(days=150, months=3):
3953
- """
3954
- days: 清理聚合数据的日期长度,days 最好大于 3 * (months +1)
3955
- months: 生成聚合数据的长度
3956
- """
3957
3826
  # 1. 更新日期表 更新货品年份基准表, 属性设置 3 - 货品年份基准
3958
3827
  date_table()
3959
3828
 
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
3829
  # 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='天猫_商品排行')
3830
+ download_manager = s_query.QueryDatas(
3831
+ username=username,
3832
+ password=password,
3833
+ host=host,
3834
+ port=port,
3835
+ maxconnections=30,
3836
+ )
3837
+ query1(download_manager=download_manager, months=months)
3838
+ query2(download_manager=download_manager, months=months)
3839
+ query3(download_manager=download_manager, months=months)
4025
3840
 
4026
3841
 
4027
3842
  if __name__ == '__main__':
4028
- main(
4029
- days=150, # 清理聚合数据的日期长度
4030
- months=3 # 生成聚合数据的长度
4031
- )
3843
+ # main(months=3)
3844
+
3845
+ pass