mdbq 4.0.25__py3-none-any.whl → 4.0.27__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mdbq/__version__.py +1 -1
- mdbq/myconf/myconf.py +40 -22
- mdbq/mysql/s_query.py +49 -7
- {mdbq-4.0.25.dist-info → mdbq-4.0.27.dist-info}/METADATA +1 -1
- {mdbq-4.0.25.dist-info → mdbq-4.0.27.dist-info}/RECORD +7 -7
- {mdbq-4.0.25.dist-info → mdbq-4.0.27.dist-info}/WHEEL +0 -0
- {mdbq-4.0.25.dist-info → mdbq-4.0.27.dist-info}/top_level.txt +0 -0
mdbq/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
VERSION = '4.0.
|
1
|
+
VERSION = '4.0.27'
|
mdbq/myconf/myconf.py
CHANGED
@@ -408,49 +408,63 @@ class ConfigParser:
|
|
408
408
|
if file_path is None:
|
409
409
|
self._ensure_file_open()
|
410
410
|
file_path = self._current_file
|
411
|
+
else:
|
412
|
+
file_path = Path(file_path)
|
413
|
+
|
411
414
|
if not self._validate_key(key):
|
412
415
|
raise ConfigException.invalid_key_error(key, file_path, section)
|
416
|
+
|
413
417
|
section = section or self.options.default_section
|
414
418
|
original_lines = []
|
415
|
-
|
416
|
-
with open(file_path, 'r', encoding=self.options.encoding) as file:
|
417
|
-
original_lines = file.readlines()
|
418
|
-
config = self.read(file_path)
|
419
|
-
if section not in config:
|
420
|
-
config[section] = {}
|
421
|
-
if value_type is not None:
|
422
|
-
try:
|
423
|
-
if value_type == bool:
|
424
|
-
if isinstance(value, str):
|
425
|
-
value = value.lower() in ('true', 'yes', '1', 'on')
|
426
|
-
else:
|
427
|
-
value = bool(value)
|
428
|
-
else:
|
429
|
-
value = value_type(value)
|
430
|
-
except (ValueError, TypeError) as e:
|
431
|
-
raise ConfigException.conversion_error(value, value_type, file_path, section=section, key=key)
|
432
|
-
if isinstance(value, bool):
|
433
|
-
value = str(value).lower()
|
434
|
-
else:
|
435
|
-
value = str(value)
|
436
|
-
config[section][key] = value
|
419
|
+
|
437
420
|
try:
|
421
|
+
if file_path.exists():
|
422
|
+
with open(file_path, 'r', encoding=self.options.encoding) as file:
|
423
|
+
original_lines = file.readlines()
|
424
|
+
|
425
|
+
config = self.read(file_path)
|
426
|
+
if section not in config:
|
427
|
+
config[section] = {}
|
428
|
+
|
429
|
+
if value_type is not None:
|
430
|
+
try:
|
431
|
+
if value_type == bool:
|
432
|
+
if isinstance(value, str):
|
433
|
+
value = value.lower() in ('true', 'yes', '1', 'on')
|
434
|
+
else:
|
435
|
+
value = bool(value)
|
436
|
+
else:
|
437
|
+
value = value_type(value)
|
438
|
+
except (ValueError, TypeError) as e:
|
439
|
+
raise ConfigException.conversion_error(value, value_type, file_path, section=section, key=key)
|
440
|
+
|
441
|
+
if isinstance(value, bool):
|
442
|
+
value = str(value).lower()
|
443
|
+
else:
|
444
|
+
value = str(value)
|
445
|
+
|
446
|
+
config[section][key] = value
|
447
|
+
|
438
448
|
file_path.parent.mkdir(parents=True, exist_ok=True)
|
439
449
|
with open(file_path, 'w', encoding=self.options.encoding) as file:
|
440
450
|
current_section = self.options.default_section
|
441
451
|
section_separators = {}
|
452
|
+
|
442
453
|
for line in original_lines:
|
443
454
|
stripped_line = line.strip()
|
444
455
|
if not stripped_line:
|
445
456
|
file.write(line)
|
446
457
|
continue
|
458
|
+
|
447
459
|
if stripped_line.startswith('[') and stripped_line.endswith(']'):
|
448
460
|
current_section = stripped_line[1:-1]
|
449
461
|
file.write(line)
|
450
462
|
continue
|
463
|
+
|
451
464
|
if self._is_comment_line(stripped_line):
|
452
465
|
file.write(line)
|
453
466
|
continue
|
467
|
+
|
454
468
|
key_value = self._split_key_value(stripped_line)
|
455
469
|
if key_value:
|
456
470
|
orig_key, orig_value = key_value
|
@@ -458,6 +472,7 @@ class ConfigParser:
|
|
458
472
|
if sep in line:
|
459
473
|
section_separators.setdefault(current_section, {})[orig_key] = sep
|
460
474
|
break
|
475
|
+
|
461
476
|
if current_section == section and orig_key == key:
|
462
477
|
separator = section_separators.get(current_section, {}).get(orig_key, self.options.separators[0])
|
463
478
|
comment = ''
|
@@ -471,10 +486,13 @@ class ConfigParser:
|
|
471
486
|
file.write(line)
|
472
487
|
else:
|
473
488
|
file.write(line)
|
489
|
+
|
474
490
|
if section not in [line.strip()[1:-1] for line in original_lines if line.strip().startswith('[') and line.strip().endswith(']')]:
|
475
491
|
file.write(f'\n[{section}]\n')
|
476
492
|
file.write(f'{key}={value}\n')
|
493
|
+
|
477
494
|
self._clear_cache(str(file_path))
|
495
|
+
|
478
496
|
except Exception as e:
|
479
497
|
raise ConfigException.write_error(file_path, e)
|
480
498
|
|
mdbq/mysql/s_query.py
CHANGED
@@ -264,7 +264,26 @@ class QueryDatas:
|
|
264
264
|
conn = self.pool.connection()
|
265
265
|
if db_name:
|
266
266
|
with conn.cursor() as cursor:
|
267
|
-
|
267
|
+
# 先检查当前数据库
|
268
|
+
cursor.execute("SELECT DATABASE()")
|
269
|
+
current_db = cursor.fetchone()['DATABASE()']
|
270
|
+
|
271
|
+
# 如果当前数据库不是目标数据库,则切换
|
272
|
+
if current_db != db_name:
|
273
|
+
cursor.execute(f"USE `{db_name}`")
|
274
|
+
# 验证切换是否成功
|
275
|
+
cursor.execute("SELECT DATABASE()")
|
276
|
+
new_db = cursor.fetchone()['DATABASE()']
|
277
|
+
if new_db != db_name:
|
278
|
+
logger.error('数据库切换失败', {
|
279
|
+
'期望数据库': db_name,
|
280
|
+
'当前数据库': new_db
|
281
|
+
})
|
282
|
+
raise ConnectionError(f'无法切换到数据库: {db_name}')
|
283
|
+
logger.debug('数据库切换成功', {
|
284
|
+
'从': current_db,
|
285
|
+
'到': db_name
|
286
|
+
})
|
268
287
|
return conn
|
269
288
|
except pymysql.OperationalError as e:
|
270
289
|
error_code = e.args[0] if e.args else None
|
@@ -353,6 +372,7 @@ class QueryDatas:
|
|
353
372
|
"""
|
354
373
|
try:
|
355
374
|
if info_type == 'exists':
|
375
|
+
# 检查数据库是否存在
|
356
376
|
result = self._execute_query("SHOW DATABASES LIKE %s", (db_name,))
|
357
377
|
if not result:
|
358
378
|
all_dbs = self._execute_query("SHOW DATABASES")
|
@@ -363,17 +383,39 @@ class QueryDatas:
|
|
363
383
|
'可能的原因': '数据库名称错误或没有访问权限'
|
364
384
|
})
|
365
385
|
return False
|
366
|
-
|
367
|
-
|
386
|
+
|
387
|
+
# 检查表是否存在(使用information_schema更可靠)
|
388
|
+
sql = """
|
389
|
+
SELECT TABLE_NAME
|
390
|
+
FROM information_schema.TABLES
|
391
|
+
WHERE TABLE_SCHEMA = %s
|
392
|
+
AND TABLE_NAME = %s
|
393
|
+
"""
|
394
|
+
result = self._execute_query(sql, (db_name, table_name))
|
368
395
|
if not result:
|
369
|
-
|
370
|
-
|
371
|
-
|
396
|
+
# 获取所有表名(不区分大小写)
|
397
|
+
sql = """
|
398
|
+
SELECT TABLE_NAME
|
399
|
+
FROM information_schema.TABLES
|
400
|
+
WHERE TABLE_SCHEMA = %s
|
401
|
+
"""
|
402
|
+
all_tables = self._execute_query(sql, (db_name,))
|
403
|
+
available_tables = [table['TABLE_NAME'] for table in all_tables] if all_tables else []
|
404
|
+
|
405
|
+
# 检查是否有大小写匹配的表
|
406
|
+
case_insensitive_matches = [t for t in available_tables if t.lower() == table_name.lower()]
|
407
|
+
|
408
|
+
error_info = {
|
372
409
|
'库': db_name,
|
373
410
|
'表': table_name,
|
374
411
|
'可用的表': available_tables,
|
375
412
|
'可能的原因': '表名称错误或没有访问权限'
|
376
|
-
}
|
413
|
+
}
|
414
|
+
|
415
|
+
if case_insensitive_matches:
|
416
|
+
error_info['可能的原因'] = f'表名大小写不匹配,请使用正确的表名: {case_insensitive_matches}'
|
417
|
+
|
418
|
+
logger.info('表不存在', error_info)
|
377
419
|
return False
|
378
420
|
return True
|
379
421
|
|
@@ -1,16 +1,16 @@
|
|
1
1
|
mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
|
2
|
-
mdbq/__version__.py,sha256=
|
2
|
+
mdbq/__version__.py,sha256=BLG9qI65B4G2SR9uwnNZDJXbyRfkGwa15Y-2HC-0wj4,18
|
3
3
|
mdbq/aggregation/__init__.py,sha256=EeDqX2Aml6SPx8363J-v1lz0EcZtgwIBYyCJV6CcEDU,40
|
4
4
|
mdbq/aggregation/query_data.py,sha256=3lvLLy1sEn5ctf4FRacFvWF-J3isK5siOSItGXmCCrg,166877
|
5
5
|
mdbq/log/__init__.py,sha256=Mpbrav0s0ifLL7lVDAuePEi1hJKiSHhxcv1byBKDl5E,15
|
6
6
|
mdbq/log/mylogger.py,sha256=9w_o5mYB3FooIxobq_lSa6oCYTKIhPxDFox-jeLtUHI,21714
|
7
7
|
mdbq/myconf/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
|
8
|
-
mdbq/myconf/myconf.py,sha256=
|
8
|
+
mdbq/myconf/myconf.py,sha256=GR250mf2KKImRUamPM2TEi9no_65tR4uKXn7eHNCAmg,31205
|
9
9
|
mdbq/myconf/myconf_bak.py,sha256=39tLUBVlWQZzQfrwk7YoLEfipo11fpwWjaLBHcUt2qM,33341
|
10
10
|
mdbq/mysql/__init__.py,sha256=A_DPJyAoEvTSFojiI2e94zP0FKtCkkwKP1kYUCSyQzo,11
|
11
11
|
mdbq/mysql/deduplicator.py,sha256=kAnkI_vnN8CchgDQAFzeh0M0vLXE2oWq9SfDPNZZ3v0,73215
|
12
12
|
mdbq/mysql/mysql.py,sha256=pDg771xBugCMSTWeskIFTi3pFLgaqgyG3smzf-86Wn8,56772
|
13
|
-
mdbq/mysql/s_query.py,sha256=
|
13
|
+
mdbq/mysql/s_query.py,sha256=UqmR592HAFzQ5mwArHisd8HFUFiNa2HJuwiIbh8N8n8,44995
|
14
14
|
mdbq/mysql/unique_.py,sha256=eA0RHGobXsMJtImMW1QvhrmguzJOYz5pX9vOA1G-gxQ,21117
|
15
15
|
mdbq/mysql/uploader.py,sha256=f1wxouaQk3narxFQ4XiAtlA0LTX_WSz3qXTkn7m_tQQ,81141
|
16
16
|
mdbq/other/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
|
@@ -25,7 +25,7 @@ mdbq/redis/__init__.py,sha256=YtgBlVSMDphtpwYX248wGge1x-Ex_mMufz4-8W0XRmA,12
|
|
25
25
|
mdbq/redis/getredis.py,sha256=vpBuNc22uj9Vr-_Dh25_wpwWM1e-072EAAIBdB_IpL0,23494
|
26
26
|
mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
|
27
27
|
mdbq/spider/aikucun.py,sha256=juOqpr_dHeE1RyjCu67VcpzoJAWMO7FKv0i8KiH8WUo,21552
|
28
|
-
mdbq-4.0.
|
29
|
-
mdbq-4.0.
|
30
|
-
mdbq-4.0.
|
31
|
-
mdbq-4.0.
|
28
|
+
mdbq-4.0.27.dist-info/METADATA,sha256=ho97HRTp4AqSe_HLBpN_L7b6MkBHmrNOqdggrG8CRwg,364
|
29
|
+
mdbq-4.0.27.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
30
|
+
mdbq-4.0.27.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
|
31
|
+
mdbq-4.0.27.dist-info/RECORD,,
|
File without changes
|
File without changes
|