mdbq 4.0.23__tar.gz → 4.0.24__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.
- {mdbq-4.0.23 → mdbq-4.0.24}/PKG-INFO +1 -1
- mdbq-4.0.24/mdbq/__version__.py +1 -0
- mdbq-4.0.23/mdbq/myconf/myconf2.py → mdbq-4.0.24/mdbq/myconf/myconf.py +258 -132
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq.egg-info/PKG-INFO +1 -1
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq.egg-info/SOURCES.txt +1 -1
- mdbq-4.0.23/mdbq/__version__.py +0 -1
- {mdbq-4.0.23 → mdbq-4.0.24}/README.txt +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/__init__.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/aggregation/__init__.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/aggregation/query_data.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/log/__init__.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/log/mylogger.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/myconf/__init__.py +0 -0
- /mdbq-4.0.23/mdbq/myconf/myconf.py → /mdbq-4.0.24/mdbq/myconf/myconf_bak.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/mysql/__init__.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/mysql/deduplicator.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/mysql/mysql.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/mysql/s_query.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/mysql/unique_.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/mysql/uploader.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/other/__init__.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/other/download_sku_picture.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/other/otk.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/other/pov_city.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/other/ua_sj.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/pbix/__init__.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/pbix/pbix_refresh.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/pbix/refresh_all.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/redis/__init__.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/redis/getredis.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/spider/__init__.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq/spider/aikucun.py +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq.egg-info/dependency_links.txt +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/mdbq.egg-info/top_level.txt +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/setup.cfg +0 -0
- {mdbq-4.0.23 → mdbq-4.0.24}/setup.py +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
VERSION = '4.0.24'
|
@@ -21,14 +21,16 @@ logger = mylogger.MyLogger(
|
|
21
21
|
T = TypeVar('T') # 类型变量
|
22
22
|
|
23
23
|
|
24
|
-
class
|
25
|
-
"""
|
24
|
+
class ConfigException(Exception):
|
25
|
+
"""配置异常基类"""
|
26
26
|
def __init__(self, message: str, file_path: Optional[Union[str, Path]] = None,
|
27
|
-
section: Optional[str] = None, key: Optional[str] = None
|
27
|
+
section: Optional[str] = None, key: Optional[str] = None,
|
28
|
+
original_error: Optional[Exception] = None):
|
28
29
|
self.message = message
|
29
30
|
self.file_path = str(file_path) if file_path else None
|
30
31
|
self.section = section
|
31
32
|
self.key = key
|
33
|
+
self.original_error = original_error
|
32
34
|
super().__init__(self._format_message())
|
33
35
|
|
34
36
|
def _format_message(self) -> str:
|
@@ -40,62 +42,69 @@ class ConfigError(Exception):
|
|
40
42
|
parts.append(f"节: [{self.section}]")
|
41
43
|
if self.key:
|
42
44
|
parts.append(f"键: {self.key}")
|
45
|
+
if self.original_error:
|
46
|
+
parts.append(f"原始错误: {str(self.original_error)}")
|
43
47
|
return " | ".join(parts)
|
44
48
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
class ConfigKeyNotFoundError(ConfigError):
|
90
|
-
"""配置键不存在异常"""
|
91
|
-
def __init__(self, file_path: Union[str, Path], section: str, key: str):
|
92
|
-
super().__init__(
|
93
|
-
f"配置键不存在",
|
49
|
+
@classmethod
|
50
|
+
def file_not_found(cls, file_path: Union[str, Path]) -> 'ConfigException':
|
51
|
+
"""配置文件不存在异常"""
|
52
|
+
return cls("配置文件不存在", file_path=file_path)
|
53
|
+
|
54
|
+
@classmethod
|
55
|
+
def read_error(cls, file_path: Union[str, Path], error: Exception) -> 'ConfigException':
|
56
|
+
"""读取配置文件失败异常"""
|
57
|
+
return cls("读取配置文件失败", file_path=file_path, original_error=error)
|
58
|
+
|
59
|
+
@classmethod
|
60
|
+
def write_error(cls, file_path: Union[str, Path], error: Exception) -> 'ConfigException':
|
61
|
+
"""写入配置文件失败异常"""
|
62
|
+
return cls("写入配置文件失败", file_path=file_path, original_error=error)
|
63
|
+
|
64
|
+
@classmethod
|
65
|
+
def value_error(cls, message: str, file_path: Union[str, Path],
|
66
|
+
section: Optional[str] = None, key: Optional[str] = None) -> 'ConfigException':
|
67
|
+
"""配置值无效异常"""
|
68
|
+
return cls(message, file_path=file_path, section=section, key=key)
|
69
|
+
|
70
|
+
@classmethod
|
71
|
+
def section_not_found(cls, file_path: Union[str, Path], section: str) -> 'ConfigException':
|
72
|
+
"""配置节不存在异常"""
|
73
|
+
return cls("配置节不存在", file_path=file_path, section=section)
|
74
|
+
|
75
|
+
@classmethod
|
76
|
+
def key_not_found(cls, file_path: Union[str, Path], section: str, key: str) -> 'ConfigException':
|
77
|
+
"""配置键不存在异常"""
|
78
|
+
return cls("配置键不存在", file_path=file_path, section=section, key=key)
|
79
|
+
|
80
|
+
@classmethod
|
81
|
+
def validation_error(cls, message: str, file_path: Union[str, Path],
|
82
|
+
section: Optional[str] = None, key: Optional[str] = None) -> 'ConfigException':
|
83
|
+
"""配置验证失败异常"""
|
84
|
+
return cls(f"配置验证失败: {message}", file_path=file_path, section=section, key=key)
|
85
|
+
|
86
|
+
@classmethod
|
87
|
+
def conversion_error(cls, value: Any, target_type: Type, file_path: Union[str, Path],
|
88
|
+
section: Optional[str] = None, key: Optional[str] = None) -> 'ConfigException':
|
89
|
+
"""类型转换失败异常"""
|
90
|
+
return cls(
|
91
|
+
f"无法将值 '{value}' 转换为类型 {target_type.__name__}",
|
94
92
|
file_path=file_path,
|
95
93
|
section=section,
|
96
94
|
key=key
|
97
95
|
)
|
98
96
|
|
97
|
+
@classmethod
|
98
|
+
def invalid_key_error(cls, key: str, file_path: Union[str, Path],
|
99
|
+
section: Optional[str] = None) -> 'ConfigException':
|
100
|
+
"""无效的键名异常"""
|
101
|
+
return cls(f"无效的键名: {key}", file_path=file_path, section=section, key=key)
|
102
|
+
|
103
|
+
@classmethod
|
104
|
+
def invalid_section_error(cls, section: str, file_path: Union[str, Path]) -> 'ConfigException':
|
105
|
+
"""无效的节名异常"""
|
106
|
+
return cls(f"无效的节名: {section}", file_path=file_path, section=section)
|
107
|
+
|
99
108
|
|
100
109
|
class CommentStyle(Enum):
|
101
110
|
"""配置文件支持的注释风格"""
|
@@ -143,14 +152,14 @@ class ConfigParser:
|
|
143
152
|
"""打开配置文件"""
|
144
153
|
file_path = Path(file_path)
|
145
154
|
if not file_path.exists() and not self.options.auto_create:
|
146
|
-
raise
|
155
|
+
raise ConfigException.file_not_found(file_path)
|
147
156
|
self._current_file = file_path
|
148
157
|
return self
|
149
158
|
|
150
159
|
def _ensure_file_open(self) -> None:
|
151
160
|
"""确保文件已打开"""
|
152
161
|
if self._current_file is None:
|
153
|
-
raise
|
162
|
+
raise ConfigException("未打开任何配置文件,请先调用 open() 方法")
|
154
163
|
|
155
164
|
def _is_comment_line(self, line: str) -> bool:
|
156
165
|
"""判断是否为注释行"""
|
@@ -204,7 +213,7 @@ class ConfigParser:
|
|
204
213
|
|
205
214
|
def _normalize_section(self, section: str) -> str:
|
206
215
|
"""标准化节名称"""
|
207
|
-
return section
|
216
|
+
return section.replace(' ', '').lower()
|
208
217
|
|
209
218
|
def _get_original_section(self, file_path: str, normalized_section: str) -> Optional[str]:
|
210
219
|
"""获取原始节名称"""
|
@@ -302,21 +311,17 @@ class ConfigParser:
|
|
302
311
|
raise ValueError("Invalid range format")
|
303
312
|
return target_type(value)
|
304
313
|
except (ValueError, TypeError) as e:
|
305
|
-
raise
|
306
|
-
f"无法将值 '{value}' 转换为类型 {target_type.__name__}",
|
307
|
-
file_path=file_path,
|
308
|
-
key=key
|
309
|
-
)
|
314
|
+
raise ConfigException.conversion_error(value, target_type, file_path, key=key)
|
310
315
|
|
311
|
-
def get_value(self,
|
312
|
-
|
313
|
-
|
316
|
+
def get_value(self, section: Optional[str] = None, key: str = None,
|
317
|
+
default: Any = None, value_type: Optional[Type[T]] = None,
|
318
|
+
file_path: Optional[Union[str, Path]] = None) -> T:
|
314
319
|
"""获取指定配置项的值"""
|
315
320
|
if file_path is None:
|
316
321
|
self._ensure_file_open()
|
317
322
|
file_path = self._current_file
|
318
323
|
if not self._validate_key(key):
|
319
|
-
raise
|
324
|
+
raise ConfigException.invalid_key_error(key, file_path, section)
|
320
325
|
config = self.read(file_path)
|
321
326
|
section = section or self.options.default_section
|
322
327
|
normalized_section = self._normalize_section(section)
|
@@ -324,20 +329,20 @@ class ConfigParser:
|
|
324
329
|
if original_section is None:
|
325
330
|
if default is not None:
|
326
331
|
return default
|
327
|
-
raise
|
332
|
+
raise ConfigException.section_not_found(file_path, section)
|
328
333
|
if key not in config[original_section]:
|
329
334
|
if default is not None:
|
330
335
|
return default
|
331
|
-
raise
|
336
|
+
raise ConfigException.key_not_found(file_path, original_section, key)
|
332
337
|
value = config[original_section][key]
|
333
338
|
if value_type is not None:
|
334
339
|
return self._convert_value(value, value_type, file_path=file_path, key=key)
|
335
340
|
return value
|
336
341
|
|
337
|
-
def get_values(self, keys: List[Tuple[str, str]],
|
338
|
-
file_path: Optional[Union[str, Path]] = None,
|
342
|
+
def get_values(self, section: Optional[str] = None, keys: List[Tuple[str, str]] = None,
|
339
343
|
defaults: Optional[Dict[str, Any]] = None,
|
340
|
-
value_types: Optional[Dict[str, Type]] = None
|
344
|
+
value_types: Optional[Dict[str, Type]] = None,
|
345
|
+
file_path: Optional[Union[str, Path]] = None) -> Dict[str, Any]:
|
341
346
|
"""批量获取多个配置项的值"""
|
342
347
|
if file_path is None:
|
343
348
|
self._ensure_file_open()
|
@@ -349,14 +354,15 @@ class ConfigParser:
|
|
349
354
|
for section, key in keys:
|
350
355
|
try:
|
351
356
|
value = self.get_value(
|
352
|
-
file_path=file_path,
|
353
|
-
key=key,
|
354
357
|
section=section,
|
358
|
+
key=key,
|
355
359
|
default=defaults.get(key),
|
356
|
-
value_type=value_types.get(key)
|
360
|
+
value_type=value_types.get(key),
|
361
|
+
file_path=file_path
|
357
362
|
)
|
358
363
|
result[key] = value
|
359
|
-
except
|
364
|
+
except ConfigException as e:
|
365
|
+
logger.error(f"读取配置项失败: section={section}, key={key}, error={e}")
|
360
366
|
if key in defaults:
|
361
367
|
result[key] = defaults[key]
|
362
368
|
else:
|
@@ -364,11 +370,10 @@ class ConfigParser:
|
|
364
370
|
|
365
371
|
return result
|
366
372
|
|
367
|
-
def get_section_values(self, keys: List[str],
|
368
|
-
section: Optional[str] = None,
|
369
|
-
file_path: Optional[Union[str, Path]] = None,
|
373
|
+
def get_section_values(self, section: Optional[str] = None, keys: List[str] = None,
|
370
374
|
defaults: Optional[Dict[str, Any]] = None,
|
371
|
-
value_types: Optional[Dict[str, Type]] = None
|
375
|
+
value_types: Optional[Dict[str, Type]] = None,
|
376
|
+
file_path: Optional[Union[str, Path]] = None) -> Tuple[Any, ...]:
|
372
377
|
"""获取指定节点下多个键的值元组"""
|
373
378
|
if file_path is None:
|
374
379
|
self._ensure_file_open()
|
@@ -380,14 +385,15 @@ class ConfigParser:
|
|
380
385
|
for key in keys:
|
381
386
|
try:
|
382
387
|
value = self.get_value(
|
383
|
-
file_path=file_path,
|
384
|
-
key=key,
|
385
388
|
section=section,
|
389
|
+
key=key,
|
386
390
|
default=defaults.get(key),
|
387
|
-
value_type=value_types.get(key)
|
391
|
+
value_type=value_types.get(key),
|
392
|
+
file_path=file_path
|
388
393
|
)
|
389
394
|
result.append(value)
|
390
|
-
except
|
395
|
+
except ConfigException as e:
|
396
|
+
logger.error(f"读取配置项失败: section={section}, key={key}, error={e}")
|
391
397
|
if key in defaults:
|
392
398
|
result.append(defaults[key])
|
393
399
|
else:
|
@@ -395,16 +401,15 @@ class ConfigParser:
|
|
395
401
|
|
396
402
|
return tuple(result)
|
397
403
|
|
398
|
-
def set_value(self, key: str, value: Any,
|
399
|
-
|
400
|
-
file_path: Optional[Union[str, Path]] = None
|
401
|
-
value_type: Optional[Type] = None) -> None:
|
404
|
+
def set_value(self, section: Optional[str] = None, key: str = None, value: Any = None,
|
405
|
+
value_type: Optional[Type] = None,
|
406
|
+
file_path: Optional[Union[str, Path]] = None) -> None:
|
402
407
|
"""设置指定配置项的值"""
|
403
408
|
if file_path is None:
|
404
409
|
self._ensure_file_open()
|
405
410
|
file_path = self._current_file
|
406
411
|
if not self._validate_key(key):
|
407
|
-
raise
|
412
|
+
raise ConfigException.invalid_key_error(key, file_path, section)
|
408
413
|
section = section or self.options.default_section
|
409
414
|
original_lines = []
|
410
415
|
if file_path.exists():
|
@@ -423,12 +428,7 @@ class ConfigParser:
|
|
423
428
|
else:
|
424
429
|
value = value_type(value)
|
425
430
|
except (ValueError, TypeError) as e:
|
426
|
-
raise
|
427
|
-
f"无法将值 '{value}' 转换为类型 {value_type.__name__}",
|
428
|
-
file_path=file_path,
|
429
|
-
section=section,
|
430
|
-
key=key
|
431
|
-
)
|
431
|
+
raise ConfigException.conversion_error(value, value_type, file_path, section=section, key=key)
|
432
432
|
if isinstance(value, bool):
|
433
433
|
value = str(value).lower()
|
434
434
|
else:
|
@@ -476,7 +476,42 @@ class ConfigParser:
|
|
476
476
|
file.write(f'{key}={value}\n')
|
477
477
|
self._clear_cache(str(file_path))
|
478
478
|
except Exception as e:
|
479
|
-
raise
|
479
|
+
raise ConfigException.write_error(file_path, e)
|
480
|
+
|
481
|
+
def set_values(self, section: Optional[str] = None, values: Dict[str, Any] = None,
|
482
|
+
value_types: Optional[Dict[str, Type]] = None,
|
483
|
+
file_path: Optional[Union[str, Path]] = None) -> None:
|
484
|
+
"""批量设置多个配置项的值"""
|
485
|
+
for key, value in values.items():
|
486
|
+
value_type = value_types.get(key) if value_types else None
|
487
|
+
self.set_value(section, key, value, value_type, file_path)
|
488
|
+
|
489
|
+
def validate_config(self, section: Optional[str] = None, schema: Dict[str, Type] = None,
|
490
|
+
file_path: Optional[Union[str, Path]] = None) -> bool:
|
491
|
+
"""验证配置是否符合指定的模式"""
|
492
|
+
config = self.read(file_path)
|
493
|
+
if section:
|
494
|
+
if section not in config:
|
495
|
+
return False
|
496
|
+
for key, expected_type in schema.items():
|
497
|
+
if key not in config[section]:
|
498
|
+
return False
|
499
|
+
try:
|
500
|
+
self._convert_value(config[section][key], expected_type)
|
501
|
+
except ConfigException:
|
502
|
+
return False
|
503
|
+
else:
|
504
|
+
for section, keys in schema.items():
|
505
|
+
if section not in config:
|
506
|
+
return False
|
507
|
+
for key, expected_type in keys.items():
|
508
|
+
if key not in config[section]:
|
509
|
+
return False
|
510
|
+
try:
|
511
|
+
self._convert_value(config[section][key], expected_type)
|
512
|
+
except ConfigException:
|
513
|
+
return False
|
514
|
+
return True
|
480
515
|
|
481
516
|
def read(self, file_path: Optional[Union[str, Path]] = None) -> Dict[str, Any]:
|
482
517
|
"""读取配置文件内容"""
|
@@ -492,7 +527,7 @@ class ConfigParser:
|
|
492
527
|
|
493
528
|
if not file_path.exists():
|
494
529
|
if not self.options.auto_create:
|
495
|
-
raise
|
530
|
+
raise ConfigException.file_not_found(file_path)
|
496
531
|
logger.info(f'配置文件不存在,将创建: {file_path}')
|
497
532
|
file_path.parent.mkdir(parents=True, exist_ok=True)
|
498
533
|
file_path.touch()
|
@@ -515,11 +550,7 @@ class ConfigParser:
|
|
515
550
|
if stripped_line.startswith('[') and stripped_line.endswith(']'):
|
516
551
|
current_section = stripped_line[1:-1]
|
517
552
|
if not self._validate_key(current_section):
|
518
|
-
raise
|
519
|
-
f"无效的节名: {current_section}",
|
520
|
-
file_path=file_path,
|
521
|
-
section=current_section
|
522
|
-
)
|
553
|
+
raise ConfigException.invalid_section_error(current_section, file_path)
|
523
554
|
self._update_section_map(str(file_path), current_section)
|
524
555
|
if current_section not in config:
|
525
556
|
config[current_section] = {}
|
@@ -532,12 +563,7 @@ class ConfigParser:
|
|
532
563
|
if key_value:
|
533
564
|
key, value = key_value
|
534
565
|
if not self._validate_key(key):
|
535
|
-
raise
|
536
|
-
f"无效的键名: {key}",
|
537
|
-
file_path=file_path,
|
538
|
-
section=current_section,
|
539
|
-
key=key
|
540
|
-
)
|
566
|
+
raise ConfigException.invalid_key_error(key, file_path, current_section)
|
541
567
|
value, comment = self._extract_comment(value)
|
542
568
|
|
543
569
|
if self.options.strip_values:
|
@@ -554,41 +580,141 @@ class ConfigParser:
|
|
554
580
|
return config
|
555
581
|
|
556
582
|
except Exception as e:
|
557
|
-
raise
|
583
|
+
raise ConfigException.read_error(file_path, e)
|
558
584
|
|
559
585
|
|
560
586
|
def main() -> None:
|
561
587
|
"""示例用法"""
|
562
|
-
config_file = Path('/Users/xigua/
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
588
|
+
config_file = Path('/Users/xigua/spd_副本.txt')
|
589
|
+
|
590
|
+
# 创建配置解析器实例
|
591
|
+
parser = ConfigParser()
|
592
|
+
# 设置配置选项
|
593
|
+
options = ConfigOptions(
|
594
|
+
comment_styles=[CommentStyle.HASH, CommentStyle.DOUBLE_SLASH],
|
595
|
+
encoding='utf-8',
|
596
|
+
auto_create=True,
|
597
|
+
strip_values=True,
|
598
|
+
preserve_comments=True,
|
599
|
+
default_section='DEFAULT',
|
600
|
+
separators=['=', ':', ':'],
|
601
|
+
cache_ttl=300,
|
602
|
+
validate_keys=True,
|
603
|
+
key_pattern=r'^[a-zA-Z0-9_\-\.]+$',
|
604
|
+
case_sensitive=False
|
605
|
+
)
|
606
|
+
parser = ConfigParser(options)
|
607
|
+
|
608
|
+
# 方式1:使用上下文管理器
|
609
|
+
with ConfigParser() as parser:
|
610
|
+
parser.open(config_file)
|
611
|
+
# 读取配置 - 最常用的参数放在前面
|
583
612
|
host, port, username, password = parser.get_section_values(
|
584
|
-
|
585
|
-
section='mysql',
|
613
|
+
section='mysql', # 最常用的section参数放在前面
|
586
614
|
keys=['host', 'port', 'username', 'password']
|
587
615
|
)
|
588
|
-
print("
|
589
|
-
|
590
|
-
|
616
|
+
print("2.1 使用上下文管理器 读取结果:", host, port, username, password)
|
617
|
+
# 修改配置
|
618
|
+
parser.set_value(
|
619
|
+
section='mysql',
|
620
|
+
key='username',
|
621
|
+
value='root'
|
622
|
+
)
|
623
|
+
parser.set_value(
|
624
|
+
section='mysql',
|
625
|
+
key='port',
|
626
|
+
value=3306,
|
627
|
+
value_type=int
|
628
|
+
)
|
629
|
+
|
630
|
+
# 方式2:链式调用
|
631
|
+
parser = ConfigParser()
|
632
|
+
host, port, username, password = parser.open(config_file).get_section_values(
|
633
|
+
section='mysql',
|
634
|
+
keys=['host', 'port', 'username', 'password']
|
635
|
+
)
|
636
|
+
print("2.2 链式调用 读取结果:", host, port, username, password)
|
637
|
+
|
638
|
+
# 方式3:传统方式
|
639
|
+
parser = ConfigParser()
|
640
|
+
host, port, username, password = parser.get_section_values(
|
641
|
+
section='mysql',
|
642
|
+
keys=['host', 'port', 'username', 'password'],
|
643
|
+
file_path=config_file # 文件路径参数放在最后
|
644
|
+
)
|
645
|
+
print("2.3 传统方式 读取结果:", host, port, username, password)
|
646
|
+
|
647
|
+
# 3.1 读取单个值 - 最常用的参数放在前面
|
648
|
+
value = parser.get_value(
|
649
|
+
section='mysql',
|
650
|
+
key='host',
|
651
|
+
default='localhost', # 默认值参数放在中间
|
652
|
+
value_type=str,
|
653
|
+
file_path=config_file
|
654
|
+
)
|
655
|
+
print("3.1 单个值读取结果:", value)
|
656
|
+
|
657
|
+
# 3.2 批量读取多个值 - 最常用的参数放在前面
|
658
|
+
values = parser.get_values(
|
659
|
+
section='mysql',
|
660
|
+
keys=[('host', 'host'), ('host', 'port')],
|
661
|
+
defaults={'host': 'localhost', 'port': 3306},
|
662
|
+
value_types={'port': int},
|
663
|
+
file_path=config_file
|
664
|
+
)
|
665
|
+
print("3.2 批量读取多个值结果:", values)
|
666
|
+
|
667
|
+
# 3.3 读取整个配置
|
668
|
+
config = parser.read(config_file)
|
669
|
+
print("3.3 读取完整配置:", config)
|
670
|
+
|
671
|
+
# 4.1 写入单个值 - 最常用的参数放在前面
|
672
|
+
parser.set_value(
|
673
|
+
section='mysql',
|
674
|
+
key='host',
|
675
|
+
value='127.0.0.1',
|
676
|
+
value_type=str,
|
677
|
+
file_path=config_file
|
678
|
+
)
|
679
|
+
print("4.1 写入单个值结果:", config_file)
|
680
|
+
|
681
|
+
# 4.2 写入不同类型的数据 - 最常用的参数放在前面
|
682
|
+
parser.open(config_file)
|
683
|
+
parser.set_value(
|
684
|
+
section='mysql',
|
685
|
+
key='port',
|
686
|
+
value=3306,
|
687
|
+
value_type=int
|
688
|
+
)
|
689
|
+
parser.set_value(
|
690
|
+
section='mysql',
|
691
|
+
key='debug',
|
692
|
+
value=True,
|
693
|
+
value_type=bool
|
694
|
+
)
|
695
|
+
parser.set_value(
|
696
|
+
section='mysql',
|
697
|
+
key='servers',
|
698
|
+
value=['server1', 'server2'],
|
699
|
+
value_type=list
|
700
|
+
)
|
701
|
+
print("4.2 写入不同类型的数据")
|
702
|
+
|
703
|
+
try:
|
704
|
+
# 尝试读取不存在的配置项 - 最常用的参数放在前面
|
705
|
+
parser.get_value(
|
706
|
+
section='mysql',
|
707
|
+
key='nonexistent'
|
708
|
+
)
|
709
|
+
except ConfigException as e:
|
710
|
+
if "配置键不存在" in str(e):
|
711
|
+
print("5.1 错误处理 配置键不存在错误:", e)
|
712
|
+
elif "配置节不存在" in str(e):
|
713
|
+
print("5.2 错误处理 配置节不存在错误:", e)
|
714
|
+
else:
|
715
|
+
print("5.3 错误处理 配置错误:", e)
|
591
716
|
|
592
717
|
|
593
718
|
if __name__ == '__main__':
|
594
719
|
main()
|
720
|
+
|
mdbq-4.0.23/mdbq/__version__.py
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
VERSION = '4.0.23'
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|