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 CHANGED
@@ -1 +1 @@
1
- VERSION = '4.0.25'
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
- if file_path.exists():
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
- cursor.execute(f"USE `{db_name}`")
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
- result = self._execute_query("SHOW TABLES LIKE %s", (table_name,), db_name=db_name)
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
- all_tables = self._execute_query("SHOW TABLES", db_name=db_name)
370
- available_tables = [table[f'Tables_in_{db_name}'] for table in all_tables] if all_tables else []
371
- logger.info('表不存在', {
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,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mdbq
3
- Version: 4.0.25
3
+ Version: 4.0.27
4
4
  Home-page: https://pypi.org/project/mdbq
5
5
  Author: xigua,
6
6
  Author-email: 2587125111@qq.com
@@ -1,16 +1,16 @@
1
1
  mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
2
- mdbq/__version__.py,sha256=mf2PMEnDnEKefV3pOhDSCsYd3oE27gy3kyQiCKjY5o0,18
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=8b3qHPKII9eh0zPHu97UiykminLjT7ePL_Bj4511wno,30737
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=RFQIWPk9kE4CDXxAni0GdhlXDTsZm36oaNjlV9VUsOU,42925
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.25.dist-info/METADATA,sha256=v8LbM8m9st9iQG2IM4JQrkaH2v6Mm44y1eHdozfv6LA,364
29
- mdbq-4.0.25.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
30
- mdbq-4.0.25.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
31
- mdbq-4.0.25.dist-info/RECORD,,
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