mdbq 4.1.2__tar.gz → 4.1.3__tar.gz
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.
Potentially problematic release.
This version of mdbq might be problematic. Click here for more details.
- {mdbq-4.1.2 → mdbq-4.1.3}/PKG-INFO +1 -1
- mdbq-4.1.3/mdbq/__version__.py +1 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/myconf/myconf.py +30 -43
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/mysql/s_query.py +1 -1
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/redis/getredis.py +33 -28
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/redis/redis_cache.py +103 -134
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/route/monitor.py +58 -201
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq.egg-info/PKG-INFO +1 -1
- mdbq-4.1.2/mdbq/__version__.py +0 -1
- {mdbq-4.1.2 → mdbq-4.1.3}/README.txt +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/__init__.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/auth/__init__.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/auth/auth_backend.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/auth/crypto.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/auth/rate_limiter.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/js/__init__.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/js/jc.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/log/__init__.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/log/mylogger.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/myconf/__init__.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/mysql/__init__.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/mysql/deduplicator.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/mysql/mysql.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/mysql/unique_.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/mysql/uploader.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/other/__init__.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/other/download_sku_picture.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/other/error_handler.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/other/otk.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/other/pov_city.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/other/ua_sj.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/pbix/__init__.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/pbix/pbix_refresh.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/pbix/refresh_all.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/redis/__init__.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/route/__init__.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/route/analytics.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/route/routes.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/selenium/__init__.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/selenium/get_driver.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq/spider/__init__.py +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq.egg-info/SOURCES.txt +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq.egg-info/dependency_links.txt +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/mdbq.egg-info/top_level.txt +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/setup.cfg +0 -0
- {mdbq-4.1.2 → mdbq-4.1.3}/setup.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VERSION = '4.1.3'
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import re
|
|
2
2
|
from typing import Dict, Any, Optional, Union, List, Tuple, Type, TypeVar
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from mdbq.log import mylogger
|
|
4
|
+
# from mdbq.log import mylogger
|
|
5
5
|
from dataclasses import dataclass, field
|
|
6
6
|
from enum import Enum
|
|
7
7
|
import time
|
|
8
8
|
|
|
9
|
-
logger = mylogger.MyLogger(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
)
|
|
9
|
+
# logger = mylogger.MyLogger(
|
|
10
|
+
# logging_mode='both',
|
|
11
|
+
# log_level='info',
|
|
12
|
+
# log_format='json',
|
|
13
|
+
# max_log_size=50,
|
|
14
|
+
# backup_count=5,
|
|
15
|
+
# enable_async=False, # 是否启用异步日志
|
|
16
|
+
# sample_rate=1, # 采样DEBUG/INFO日志
|
|
17
|
+
# sensitive_fields=[], # 敏感字段过滤
|
|
18
|
+
# enable_metrics=False, # 是否启用性能指标
|
|
19
|
+
# )
|
|
20
20
|
|
|
21
21
|
T = TypeVar('T') # 类型变量
|
|
22
22
|
|
|
@@ -151,12 +151,10 @@ class ConfigParser:
|
|
|
151
151
|
def open(self, file_path: Union[str, Path]) -> 'ConfigParser':
|
|
152
152
|
"""打开配置文件"""
|
|
153
153
|
file_path = Path(file_path)
|
|
154
|
-
logger.debug(f'尝试打开配置文件: {file_path}')
|
|
155
154
|
if not file_path.exists() and not self.options.auto_create:
|
|
156
|
-
logger.error(f'配置文件不存在: {file_path}')
|
|
155
|
+
# logger.error(f'配置文件不存在: {file_path}')
|
|
157
156
|
raise ConfigException.file_not_found(file_path)
|
|
158
157
|
self._current_file = file_path
|
|
159
|
-
logger.debug(f'配置文件已打开: {file_path}')
|
|
160
158
|
return self
|
|
161
159
|
|
|
162
160
|
def _ensure_file_open(self) -> None:
|
|
@@ -211,7 +209,6 @@ class ConfigParser:
|
|
|
211
209
|
|
|
212
210
|
def _update_cache(self, file_path: str, config: Dict[str, Any]) -> None:
|
|
213
211
|
"""更新配置缓存"""
|
|
214
|
-
logger.debug(f'更新配置缓存: {file_path}')
|
|
215
212
|
self._config_cache[file_path] = config
|
|
216
213
|
self._cache_timestamps[file_path] = time.time()
|
|
217
214
|
|
|
@@ -236,13 +233,11 @@ class ConfigParser:
|
|
|
236
233
|
def _clear_cache(self, file_path: Optional[str] = None) -> None:
|
|
237
234
|
"""清除配置缓存"""
|
|
238
235
|
if file_path:
|
|
239
|
-
logger.debug(f'清除指定文件的缓存: {file_path}')
|
|
240
236
|
self._config_cache.pop(file_path, None)
|
|
241
237
|
self._cache_timestamps.pop(file_path, None)
|
|
242
238
|
self._comments_cache.pop(file_path, None)
|
|
243
239
|
self._section_map.pop(file_path, None)
|
|
244
240
|
else:
|
|
245
|
-
logger.debug('清除所有配置缓存')
|
|
246
241
|
self._config_cache.clear()
|
|
247
242
|
self._cache_timestamps.clear()
|
|
248
243
|
self._comments_cache.clear()
|
|
@@ -323,12 +318,11 @@ class ConfigParser:
|
|
|
323
318
|
default: Any = None, value_type: Optional[Type[T]] = None,
|
|
324
319
|
file_path: Optional[Union[str, Path]] = None) -> T:
|
|
325
320
|
"""获取指定配置项的值"""
|
|
326
|
-
logger.debug(f'获取配置项: section={section}, key={key}, file_path={file_path}')
|
|
327
321
|
if file_path is None:
|
|
328
322
|
self._ensure_file_open()
|
|
329
323
|
file_path = self._current_file
|
|
330
324
|
if not self._validate_key(key):
|
|
331
|
-
logger.error(f'无效的键名: {key}')
|
|
325
|
+
# logger.error(f'无效的键名: {key}')
|
|
332
326
|
raise ConfigException.invalid_key_error(key, file_path, section)
|
|
333
327
|
config = self.read(file_path)
|
|
334
328
|
section = section or self.options.default_section
|
|
@@ -336,15 +330,15 @@ class ConfigParser:
|
|
|
336
330
|
original_section = self._get_original_section(str(file_path), normalized_section)
|
|
337
331
|
if original_section is None:
|
|
338
332
|
if default is not None:
|
|
339
|
-
logger.warning(f'节不存在,返回默认值: section={section}, key={key}, default={default}')
|
|
333
|
+
# logger.warning(f'节不存在,返回默认值: section={section}, key={key}, default={default}')
|
|
340
334
|
return default
|
|
341
|
-
logger.error(f'配置节不存在: {section}')
|
|
335
|
+
# logger.error(f'配置节不存在: {section}')
|
|
342
336
|
raise ConfigException.section_not_found(file_path, section)
|
|
343
337
|
if key not in config[original_section]:
|
|
344
338
|
if default is not None:
|
|
345
|
-
logger.warning(f'键不存在,返回默认值: section={section}, key={key}, default={default}')
|
|
339
|
+
# logger.warning(f'键不存在,返回默认值: section={section}, key={key}, default={default}')
|
|
346
340
|
return default
|
|
347
|
-
logger.error(f'配置键不存在: {key}')
|
|
341
|
+
# logger.error(f'配置键不存在: {key}')
|
|
348
342
|
raise ConfigException.key_not_found(file_path, original_section, key)
|
|
349
343
|
value = config[original_section][key]
|
|
350
344
|
if value_type is not None:
|
|
@@ -356,7 +350,6 @@ class ConfigParser:
|
|
|
356
350
|
value_types: Optional[Dict[str, Type]] = None,
|
|
357
351
|
file_path: Optional[Union[str, Path]] = None) -> Dict[str, Any]:
|
|
358
352
|
"""批量获取多个配置项的值"""
|
|
359
|
-
logger.debug(f'批量获取配置项: section={section}, keys={keys}, file_path={file_path}')
|
|
360
353
|
if file_path is None:
|
|
361
354
|
self._ensure_file_open()
|
|
362
355
|
file_path = self._current_file
|
|
@@ -375,7 +368,7 @@ class ConfigParser:
|
|
|
375
368
|
)
|
|
376
369
|
result[key] = value
|
|
377
370
|
except ConfigException as e:
|
|
378
|
-
logger.error(f"读取配置项失败: section={section}, key={key}, error={e}")
|
|
371
|
+
# logger.error(f"读取配置项失败: section={section}, key={key}, error={e}")
|
|
379
372
|
if key in defaults:
|
|
380
373
|
result[key] = defaults[key]
|
|
381
374
|
else:
|
|
@@ -388,7 +381,6 @@ class ConfigParser:
|
|
|
388
381
|
value_types: Optional[Dict[str, Type]] = None,
|
|
389
382
|
file_path: Optional[Union[str, Path]] = None) -> Tuple[Any, ...]:
|
|
390
383
|
"""获取指定节点下多个键的值元组"""
|
|
391
|
-
logger.debug(f'获取节下多个键的值: section={section}, keys={keys}, file_path={file_path}')
|
|
392
384
|
if file_path is None:
|
|
393
385
|
self._ensure_file_open()
|
|
394
386
|
file_path = self._current_file
|
|
@@ -407,7 +399,7 @@ class ConfigParser:
|
|
|
407
399
|
)
|
|
408
400
|
result.append(value)
|
|
409
401
|
except ConfigException as e:
|
|
410
|
-
logger.error(f"读取配置项失败: section={section}, key={key}, error={e}")
|
|
402
|
+
# logger.error(f"读取配置项失败: section={section}, key={key}, error={e}")
|
|
411
403
|
if key in defaults:
|
|
412
404
|
result.append(defaults[key])
|
|
413
405
|
else:
|
|
@@ -419,7 +411,6 @@ class ConfigParser:
|
|
|
419
411
|
value_type: Optional[Type] = None,
|
|
420
412
|
file_path: Optional[Union[str, Path]] = None) -> None:
|
|
421
413
|
"""设置指定配置项的值"""
|
|
422
|
-
logger.debug(f'准备写入配置项: section={section}, key={key}, value={value}, file_path={file_path}')
|
|
423
414
|
if file_path is None:
|
|
424
415
|
self._ensure_file_open()
|
|
425
416
|
file_path = self._current_file
|
|
@@ -427,7 +418,7 @@ class ConfigParser:
|
|
|
427
418
|
file_path = Path(file_path)
|
|
428
419
|
|
|
429
420
|
if not self._validate_key(key):
|
|
430
|
-
logger.error(f'无效的键名: {key}')
|
|
421
|
+
# logger.error(f'无效的键名: {key}')
|
|
431
422
|
raise ConfigException.invalid_key_error(key, file_path, section)
|
|
432
423
|
|
|
433
424
|
section = section or self.options.default_section
|
|
@@ -452,7 +443,7 @@ class ConfigParser:
|
|
|
452
443
|
else:
|
|
453
444
|
value = value_type(value)
|
|
454
445
|
except (ValueError, TypeError) as e:
|
|
455
|
-
logger.error(f'类型转换失败: value={value}, type={value_type}, error={e}')
|
|
446
|
+
# logger.error(f'类型转换失败: value={value}, type={value_type}, error={e}')
|
|
456
447
|
raise ConfigException.conversion_error(value, value_type, file_path, section=section, key=key)
|
|
457
448
|
|
|
458
449
|
if isinstance(value, bool):
|
|
@@ -509,21 +500,20 @@ class ConfigParser:
|
|
|
509
500
|
file.write(f'{key}={value}\n')
|
|
510
501
|
|
|
511
502
|
self._clear_cache(str(file_path))
|
|
512
|
-
logger.info(f'配置项写入成功: section={section}, key={key}, value={value}, file_path={file_path}')
|
|
503
|
+
# logger.info(f'配置项写入成功: section={section}, key={key}, value={value}, file_path={file_path}')
|
|
513
504
|
|
|
514
505
|
except Exception as e:
|
|
515
|
-
logger.error(f'写入配置项失败: section={section}, key={key}, value={value}, file_path={file_path}, error={e}')
|
|
506
|
+
# logger.error(f'写入配置项失败: section={section}, key={key}, value={value}, file_path={file_path}, error={e}')
|
|
516
507
|
raise ConfigException.write_error(file_path, e)
|
|
517
508
|
|
|
518
509
|
def set_values(self, section: Optional[str] = None, values: Dict[str, Any] = None,
|
|
519
510
|
value_types: Optional[Dict[str, Type]] = None,
|
|
520
511
|
file_path: Optional[Union[str, Path]] = None) -> None:
|
|
521
512
|
"""批量设置多个配置项的值"""
|
|
522
|
-
logger.debug(f'批量写入配置项: section={section}, keys={list(values.keys())}, file_path={file_path}')
|
|
523
513
|
for key, value in values.items():
|
|
524
514
|
value_type = value_types.get(key) if value_types else None
|
|
525
515
|
self.set_value(section, key, value, value_type, file_path)
|
|
526
|
-
logger.info(f'批量写入配置项完成: section={section}, file_path={file_path}')
|
|
516
|
+
# logger.info(f'批量写入配置项完成: section={section}, file_path={file_path}')
|
|
527
517
|
|
|
528
518
|
def validate_config(self, section: Optional[str] = None, schema: Dict[str, Type] = None,
|
|
529
519
|
file_path: Optional[Union[str, Path]] = None) -> bool:
|
|
@@ -560,17 +550,15 @@ class ConfigParser:
|
|
|
560
550
|
else:
|
|
561
551
|
file_path = Path(file_path)
|
|
562
552
|
|
|
563
|
-
logger.debug(f'开始读取配置文件: {file_path}')
|
|
564
553
|
cached_config = self._get_cached_config(str(file_path))
|
|
565
554
|
if cached_config is not None:
|
|
566
|
-
logger.debug(f'命中配置缓存: {file_path}')
|
|
567
555
|
return cached_config
|
|
568
556
|
|
|
569
557
|
if not file_path.exists():
|
|
570
558
|
if not self.options.auto_create:
|
|
571
|
-
logger.error(f'配置文件不存在: {file_path}')
|
|
559
|
+
# logger.error(f'配置文件不存在: {file_path}')
|
|
572
560
|
raise ConfigException.file_not_found(file_path)
|
|
573
|
-
logger.info(f'配置文件不存在,将创建: {file_path}')
|
|
561
|
+
# logger.info(f'配置文件不存在,将创建: {file_path}')
|
|
574
562
|
file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
575
563
|
file_path.touch()
|
|
576
564
|
return {}
|
|
@@ -592,7 +580,7 @@ class ConfigParser:
|
|
|
592
580
|
if stripped_line.startswith('[') and stripped_line.endswith(']'):
|
|
593
581
|
current_section = stripped_line[1:-1]
|
|
594
582
|
if not self._validate_key(current_section):
|
|
595
|
-
logger.error(f'无效的节名: {current_section}')
|
|
583
|
+
# logger.error(f'无效的节名: {current_section}')
|
|
596
584
|
raise ConfigException.invalid_section_error(current_section, file_path)
|
|
597
585
|
self._update_section_map(str(file_path), current_section)
|
|
598
586
|
if current_section not in config:
|
|
@@ -606,7 +594,7 @@ class ConfigParser:
|
|
|
606
594
|
if key_value:
|
|
607
595
|
key, value = key_value
|
|
608
596
|
if not self._validate_key(key):
|
|
609
|
-
logger.error(f'无效的键名: {key}')
|
|
597
|
+
# logger.error(f'无效的键名: {key}')
|
|
610
598
|
raise ConfigException.invalid_key_error(key, file_path, current_section)
|
|
611
599
|
value, comment = self._extract_comment(value)
|
|
612
600
|
|
|
@@ -621,11 +609,10 @@ class ConfigParser:
|
|
|
621
609
|
self._comments_cache.setdefault(str(file_path), {}).setdefault(current_section, []).append(comment)
|
|
622
610
|
|
|
623
611
|
self._update_cache(str(file_path), config)
|
|
624
|
-
logger.debug(f'配置文件读取成功: {file_path}')
|
|
625
612
|
return config
|
|
626
613
|
|
|
627
614
|
except Exception as e:
|
|
628
|
-
logger.error(f'读取配置文件失败: {file_path}, error={e}')
|
|
615
|
+
# logger.error(f'读取配置文件失败: {file_path}, error={e}')
|
|
629
616
|
raise ConfigException.read_error(file_path, e)
|
|
630
617
|
|
|
631
618
|
|
|
@@ -5,21 +5,21 @@ import numpy as np
|
|
|
5
5
|
import json
|
|
6
6
|
import datetime
|
|
7
7
|
import threading
|
|
8
|
-
from mdbq.log import mylogger
|
|
8
|
+
# from mdbq.log import mylogger
|
|
9
9
|
from decimal import Decimal
|
|
10
10
|
import orjson
|
|
11
11
|
|
|
12
|
-
logger = mylogger.MyLogger(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
)
|
|
12
|
+
# logger = mylogger.MyLogger(
|
|
13
|
+
# logging_mode='file',
|
|
14
|
+
# log_level='info',
|
|
15
|
+
# log_format='json',
|
|
16
|
+
# max_log_size=50,
|
|
17
|
+
# backup_count=5,
|
|
18
|
+
# enable_async=False, # 是否启用异步日志
|
|
19
|
+
# sample_rate=1, # 采样DEBUG/INFO日志
|
|
20
|
+
# sensitive_fields=[], # 敏感字段过滤
|
|
21
|
+
# enable_metrics=False, # 是否启用性能指标
|
|
22
|
+
# )
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class RedisData(object):
|
|
@@ -61,7 +61,8 @@ class RedisData(object):
|
|
|
61
61
|
|
|
62
62
|
combined_df = pd.concat(dfs, ignore_index=True) if dfs else pd.DataFrame()
|
|
63
63
|
if combined_df.empty:
|
|
64
|
-
logger.info(f"警告: {db_name}.{table_name} 未读取到数据")
|
|
64
|
+
# logger.info(f"警告: {db_name}.{table_name} 未读取到数据")
|
|
65
|
+
pass
|
|
65
66
|
else:
|
|
66
67
|
combined_df = self._convert_date_columns(combined_df)
|
|
67
68
|
return combined_df
|
|
@@ -86,7 +87,7 @@ class RedisData(object):
|
|
|
86
87
|
ttl = self.redis_engine.ttl(cache_key)
|
|
87
88
|
cache_data = self._fetch_redis_data(cache_key)
|
|
88
89
|
except Exception as e:
|
|
89
|
-
logger.error(f"Redis 连接异常: {e},直接访问 MySQL")
|
|
90
|
+
# logger.error(f"Redis 连接异常: {e},直接访问 MySQL")
|
|
90
91
|
return self.get_from_mysql(db_name, table_name, set_year, start_date, end_date)
|
|
91
92
|
|
|
92
93
|
# 缓存失效处理逻辑
|
|
@@ -134,11 +135,11 @@ class RedisData(object):
|
|
|
134
135
|
self.redis_engine.set(cache_key, serialized_data)
|
|
135
136
|
self.redis_engine.expire(cache_key, self.cache_ttl)
|
|
136
137
|
|
|
137
|
-
logger.info(f"缓存更新 {cache_key} | 数据量: {len(combined_data)}")
|
|
138
|
+
# logger.info(f"缓存更新 {cache_key} | 数据量: {len(combined_data)}")
|
|
138
139
|
return combined_data
|
|
139
140
|
|
|
140
141
|
except Exception as e:
|
|
141
|
-
logger.error(f"缓存更新失败: {cache_key} - {str(e)}")
|
|
142
|
+
# logger.error(f"缓存更新失败: {cache_key} - {str(e)}")
|
|
142
143
|
return pd.DataFrame()
|
|
143
144
|
|
|
144
145
|
# Helper Methods ------------------------------------------------
|
|
@@ -160,7 +161,7 @@ class RedisData(object):
|
|
|
160
161
|
projection={}
|
|
161
162
|
)
|
|
162
163
|
except Exception as e:
|
|
163
|
-
logger.error(f"MySQL 查询异常 {db_name}.{table_name}: {e}")
|
|
164
|
+
# logger.error(f"MySQL 查询异常 {db_name}.{table_name}: {e}")
|
|
164
165
|
return pd.DataFrame()
|
|
165
166
|
|
|
166
167
|
def _fetch_redis_data(self, cache_key: str) -> pd.DataFrame:
|
|
@@ -173,7 +174,7 @@ class RedisData(object):
|
|
|
173
174
|
df = pd.DataFrame(json.loads(data.decode("utf-8")))
|
|
174
175
|
return self._convert_date_columns(df)
|
|
175
176
|
except Exception as e:
|
|
176
|
-
logger.error(f"Redis 数据解析失败 {cache_key}: {e}")
|
|
177
|
+
# logger.error(f"Redis 数据解析失败 {cache_key}: {e}")
|
|
177
178
|
return pd.DataFrame()
|
|
178
179
|
|
|
179
180
|
def _convert_date_columns(self, df: pd.DataFrame) -> pd.DataFrame:
|
|
@@ -278,7 +279,8 @@ class RedisDataHash(object):
|
|
|
278
279
|
|
|
279
280
|
combined_df = pd.concat(dfs, ignore_index=True) if dfs else pd.DataFrame()
|
|
280
281
|
if combined_df.empty:
|
|
281
|
-
logger.warn(f"warning: {db_name}.{table_name} 未读取到数据")
|
|
282
|
+
# logger.warn(f"warning: {db_name}.{table_name} 未读取到数据")
|
|
283
|
+
pass
|
|
282
284
|
else:
|
|
283
285
|
combined_df = self._convert_date_columns(combined_df)
|
|
284
286
|
return combined_df
|
|
@@ -293,7 +295,7 @@ class RedisDataHash(object):
|
|
|
293
295
|
projection={}
|
|
294
296
|
) -> pd.DataFrame:
|
|
295
297
|
if not self.redis_engine.ping():
|
|
296
|
-
logger.error(f"Redis ping异常,直接访问 MySQL")
|
|
298
|
+
# logger.error(f"Redis ping异常,直接访问 MySQL")
|
|
297
299
|
return self.get_from_mysql(db_name, table_name, set_year, start_date, end_date, projection)
|
|
298
300
|
start_dt = pd.to_datetime(start_date).floor('D')
|
|
299
301
|
end_dt = pd.to_datetime(end_date).floor('D')
|
|
@@ -335,7 +337,7 @@ class RedisDataHash(object):
|
|
|
335
337
|
return self.get_from_mysql(db_name, table_name, set_year, start_date, end_date, projection)
|
|
336
338
|
|
|
337
339
|
except Exception as e:
|
|
338
|
-
logger.error(f"Redis 连接异常: {e},直接访问 MySQL")
|
|
340
|
+
# logger.error(f"Redis 连接异常: {e},直接访问 MySQL")
|
|
339
341
|
return self.get_from_mysql(db_name, table_name, set_year, start_date, end_date, projection)
|
|
340
342
|
|
|
341
343
|
def set_redis(
|
|
@@ -385,9 +387,10 @@ class RedisDataHash(object):
|
|
|
385
387
|
serialized_data = self._serialize_data(group)
|
|
386
388
|
self.redis_engine.hset(cache_key, month_str, serialized_data)
|
|
387
389
|
self.redis_engine.expire(cache_key, self.cache_ttl + random.randint(0, 1800))
|
|
388
|
-
logger.info(f"缓存更新 {cache_key} | 数据量: {len(combined_data)}")
|
|
390
|
+
# logger.info(f"缓存更新 {cache_key} | 数据量: {len(combined_data)}")
|
|
389
391
|
except Exception as e:
|
|
390
|
-
logger.error(f"缓存更新失败: {cache_key} - {str(e)}")
|
|
392
|
+
# logger.error(f"缓存更新失败: {cache_key} - {str(e)}")
|
|
393
|
+
pass
|
|
391
394
|
|
|
392
395
|
def _fetch_table_data(
|
|
393
396
|
self,
|
|
@@ -406,7 +409,7 @@ class RedisDataHash(object):
|
|
|
406
409
|
projection=projection
|
|
407
410
|
)
|
|
408
411
|
except Exception as e:
|
|
409
|
-
logger.error(f"MySQL 查询异常 {db_name}.{table_name}: {e}")
|
|
412
|
+
# logger.error(f"MySQL 查询异常 {db_name}.{table_name}: {e}")
|
|
410
413
|
return pd.DataFrame()
|
|
411
414
|
|
|
412
415
|
def _fetch_redis_data(self, cache_key: str, months: list = None) -> pd.DataFrame:
|
|
@@ -441,7 +444,8 @@ class RedisDataHash(object):
|
|
|
441
444
|
df = self._convert_date_columns(df)
|
|
442
445
|
dfs.append(df)
|
|
443
446
|
except Exception as e:
|
|
444
|
-
logger.error(f"月份数据解析失败 {field}: {e}")
|
|
447
|
+
# logger.error(f"月份数据解析失败 {field}: {e}")
|
|
448
|
+
pass
|
|
445
449
|
|
|
446
450
|
# 处理分片数据(优化后的批处理逻辑)
|
|
447
451
|
cursor, shard_data = results[result_index]
|
|
@@ -459,7 +463,8 @@ class RedisDataHash(object):
|
|
|
459
463
|
df = pd.DataFrame(orjson.loads(value))
|
|
460
464
|
dfs.append(self._convert_date_columns(df))
|
|
461
465
|
except Exception as e:
|
|
462
|
-
logger.error(f"分片数据解析失败: {e}")
|
|
466
|
+
# logger.error(f"分片数据解析失败: {e}")
|
|
467
|
+
pass
|
|
463
468
|
|
|
464
469
|
# 继续获取后续分片
|
|
465
470
|
if cursor == 0:
|
|
@@ -475,7 +480,7 @@ class RedisDataHash(object):
|
|
|
475
480
|
return pd.DataFrame()
|
|
476
481
|
|
|
477
482
|
except Exception as e:
|
|
478
|
-
logger.error(f"Redis 数据获取失败 {cache_key}: {e}")
|
|
483
|
+
# logger.error(f"Redis 数据获取失败 {cache_key}: {e}")
|
|
479
484
|
return pd.DataFrame()
|
|
480
485
|
|
|
481
486
|
def _convert_date_columns(self, df: pd.DataFrame) -> pd.DataFrame:
|
|
@@ -562,7 +567,7 @@ class RedisDataHash(object):
|
|
|
562
567
|
try:
|
|
563
568
|
records = temp_df.to_dict(orient='records')
|
|
564
569
|
except Exception as e:
|
|
565
|
-
logger.error(f"DataFrame转字典失败: {str(e)}")
|
|
570
|
+
# logger.error(f"DataFrame转字典失败: {str(e)}")
|
|
566
571
|
records = []
|
|
567
572
|
|
|
568
573
|
# 序列化配置 --------------------------------------------------------
|