mdbq 4.2.5__tar.gz → 4.2.7__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.2.5 → mdbq-4.2.7}/PKG-INFO +2 -2
- mdbq-4.2.7/mdbq/__version__.py +1 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/mysql/uploader.py +55 -60
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq.egg-info/PKG-INFO +2 -2
- mdbq-4.2.5/mdbq/__version__.py +0 -1
- {mdbq-4.2.5 → mdbq-4.2.7}/README.txt +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/__init__.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/auth/__init__.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/auth/auth_backend.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/auth/crypto.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/auth/rate_limiter.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/js/__init__.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/js/jc.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/log/__init__.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/log/mylogger.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/myconf/__init__.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/myconf/myconf.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/mysql/__init__.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/mysql/deduplicator.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/mysql/mysql.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/mysql/s_query.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/mysql/unique_.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/other/__init__.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/other/download_sku_picture.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/other/error_handler.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/other/otk.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/other/pov_city.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/other/ua_sj.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/pbix/__init__.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/pbix/pbix_refresh.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/pbix/refresh_all.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/redis/__init__.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/redis/getredis.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/redis/redis_cache.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/route/__init__.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/route/analytics.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/route/monitor.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/route/routes.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/selenium/__init__.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/selenium/get_driver.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq/spider/__init__.py +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq.egg-info/SOURCES.txt +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq.egg-info/dependency_links.txt +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/mdbq.egg-info/top_level.txt +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/setup.cfg +0 -0
- {mdbq-4.2.5 → mdbq-4.2.7}/setup.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VERSION = '4.2.7'
|
|
@@ -701,11 +701,41 @@ class TableManager:
|
|
|
701
701
|
# 过滤掉系统列
|
|
702
702
|
filtered_uk = [col for col in uk if col.lower() not in ['id', 'create_at', 'update_at']]
|
|
703
703
|
if filtered_uk:
|
|
704
|
-
#
|
|
705
|
-
|
|
706
|
-
|
|
704
|
+
# 先清理列名标识符,再应用前缀索引
|
|
705
|
+
safe_uk_parts = []
|
|
706
|
+
for col in filtered_uk:
|
|
707
|
+
safe_col_name = self._sanitize_identifier(col)
|
|
708
|
+
# 检查是否需要前缀索引
|
|
709
|
+
col_type = columns.get(col, 'varchar(255)').lower()
|
|
710
|
+
if 'varchar' in col_type:
|
|
711
|
+
# 提取varchar长度
|
|
712
|
+
match = re.search(r'varchar\((\d+)\)', col_type)
|
|
713
|
+
if match:
|
|
714
|
+
length = int(match.group(1))
|
|
715
|
+
# 如果varchar长度超过191字符,使用前缀索引
|
|
716
|
+
if length > 191:
|
|
717
|
+
prefix_length = 191
|
|
718
|
+
safe_uk_parts.append(f"`{safe_col_name}`({prefix_length})")
|
|
719
|
+
logger.debug('应用前缀索引', {
|
|
720
|
+
'列名': col,
|
|
721
|
+
'原始长度': length,
|
|
722
|
+
'前缀长度': prefix_length
|
|
723
|
+
})
|
|
724
|
+
else:
|
|
725
|
+
safe_uk_parts.append(f"`{safe_col_name}`")
|
|
726
|
+
else:
|
|
727
|
+
# 如果没有指定长度,默认使用前缀索引
|
|
728
|
+
safe_uk_parts.append(f"`{safe_col_name}`(191)")
|
|
729
|
+
logger.debug('应用默认前缀索引', {
|
|
730
|
+
'列名': col,
|
|
731
|
+
'前缀长度': 191
|
|
732
|
+
})
|
|
733
|
+
else:
|
|
734
|
+
# 非varchar字段保持原样
|
|
735
|
+
safe_uk_parts.append(f"`{safe_col_name}`")
|
|
736
|
+
|
|
707
737
|
unique_name = f"uniq_{i}"
|
|
708
|
-
unique_defs.append(f"UNIQUE KEY `{unique_name}` ({','.join(
|
|
738
|
+
unique_defs.append(f"UNIQUE KEY `{unique_name}` ({','.join(safe_uk_parts)})")
|
|
709
739
|
|
|
710
740
|
# 组合所有定义
|
|
711
741
|
all_defs = column_defs + [primary_key_def] + unique_defs
|
|
@@ -740,8 +770,7 @@ class TableManager:
|
|
|
740
770
|
except Exception as e:
|
|
741
771
|
raise ValueError(f"无效的日期值: {date_value}, 错误: {str(e)}")
|
|
742
772
|
|
|
743
|
-
|
|
744
|
-
def _sanitize_identifier(identifier: str) -> str:
|
|
773
|
+
def _sanitize_identifier(self, identifier: str) -> str:
|
|
745
774
|
"""清理标识符"""
|
|
746
775
|
if not identifier or not isinstance(identifier, str):
|
|
747
776
|
raise ValueError(f"无效的标识符: {identifier}")
|
|
@@ -753,63 +782,19 @@ class TableManager:
|
|
|
753
782
|
if not cleaned:
|
|
754
783
|
raise ValueError(f"标识符清理后为空: {identifier}")
|
|
755
784
|
|
|
756
|
-
# 检查MySQL关键字
|
|
757
|
-
mysql_keywords = {
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
}
|
|
785
|
+
# # 检查MySQL关键字
|
|
786
|
+
# mysql_keywords = {
|
|
787
|
+
# 'select', 'insert', 'update', 'delete', 'from', 'where', 'and', 'or',
|
|
788
|
+
# 'not', 'like', 'in', 'is', 'null', 'true', 'false', 'between'
|
|
789
|
+
# }
|
|
761
790
|
|
|
762
791
|
if len(cleaned) > 64:
|
|
763
792
|
cleaned = cleaned[:64]
|
|
764
793
|
|
|
765
|
-
|
|
766
|
-
return f"`{cleaned}`"
|
|
767
|
-
|
|
794
|
+
# 不在这里添加反引号,让调用者决定是否需要
|
|
768
795
|
return cleaned
|
|
769
796
|
|
|
770
|
-
|
|
771
|
-
"""
|
|
772
|
-
为超长的varchar字段应用前缀索引,防止索引键长度超限
|
|
773
|
-
|
|
774
|
-
:param columns: 列名列表
|
|
775
|
-
:param column_definitions: 列定义字典
|
|
776
|
-
:return: 应用前缀索引后的列名列表
|
|
777
|
-
"""
|
|
778
|
-
optimized_columns = []
|
|
779
|
-
|
|
780
|
-
for col in columns:
|
|
781
|
-
col_type = column_definitions.get(col, 'varchar(255)').lower()
|
|
782
|
-
|
|
783
|
-
# 只对varchar字段应用前缀索引
|
|
784
|
-
if 'varchar' in col_type:
|
|
785
|
-
# 提取varchar长度
|
|
786
|
-
match = re.search(r'varchar\((\d+)\)', col_type)
|
|
787
|
-
if match:
|
|
788
|
-
length = int(match.group(1))
|
|
789
|
-
# 如果varchar长度超过191字符,使用前缀索引
|
|
790
|
-
# 191 * 4 = 764字节,在3072字节限制内比较安全
|
|
791
|
-
if length > 191:
|
|
792
|
-
prefix_length = 191 # 使用191字符作为前缀
|
|
793
|
-
optimized_columns.append(f"{col}({prefix_length})")
|
|
794
|
-
logger.info('应用前缀索引', {
|
|
795
|
-
'列名': col,
|
|
796
|
-
'原始长度': length,
|
|
797
|
-
'前缀长度': prefix_length
|
|
798
|
-
})
|
|
799
|
-
else:
|
|
800
|
-
optimized_columns.append(col)
|
|
801
|
-
else:
|
|
802
|
-
# 如果没有指定长度,默认使用前缀索引
|
|
803
|
-
optimized_columns.append(f"{col}(191)")
|
|
804
|
-
logger.info('应用默认前缀索引', {
|
|
805
|
-
'列名': col,
|
|
806
|
-
'前缀长度': 191
|
|
807
|
-
})
|
|
808
|
-
else:
|
|
809
|
-
# 非varchar字段保持原样
|
|
810
|
-
optimized_columns.append(col)
|
|
811
|
-
|
|
812
|
-
return optimized_columns
|
|
797
|
+
|
|
813
798
|
|
|
814
799
|
|
|
815
800
|
class DataProcessor:
|
|
@@ -930,8 +915,9 @@ class DataProcessor:
|
|
|
930
915
|
class DataInserter:
|
|
931
916
|
"""数据插入器"""
|
|
932
917
|
|
|
933
|
-
def __init__(self, connection_manager: DatabaseConnectionManager):
|
|
918
|
+
def __init__(self, connection_manager: DatabaseConnectionManager, table_manager: TableManager = None):
|
|
934
919
|
self.conn_mgr = connection_manager
|
|
920
|
+
self.table_mgr = table_manager
|
|
935
921
|
|
|
936
922
|
def insert_data(self, db_name: str, table_name: str, data: List[Dict],
|
|
937
923
|
set_typ: Dict[str, str], update_on_duplicate: bool = False) -> Tuple[int, int, int]:
|
|
@@ -941,7 +927,7 @@ class DataInserter:
|
|
|
941
927
|
|
|
942
928
|
# 准备SQL语句(排除系统列)
|
|
943
929
|
columns = [col for col in set_typ.keys() if col.lower() not in ['id', 'create_at', 'update_at']]
|
|
944
|
-
safe_columns = [
|
|
930
|
+
safe_columns = [self.table_mgr._sanitize_identifier(col) if self.table_mgr else col for col in columns]
|
|
945
931
|
placeholders = ','.join(['%s'] * len(columns))
|
|
946
932
|
|
|
947
933
|
sql = f"""
|
|
@@ -1110,7 +1096,7 @@ class MySQLUploader:
|
|
|
1110
1096
|
# 初始化组件
|
|
1111
1097
|
self.conn_mgr = DatabaseConnectionManager(self.config)
|
|
1112
1098
|
self.table_mgr = TableManager(self.conn_mgr, collation)
|
|
1113
|
-
self.data_inserter = DataInserter(self.conn_mgr)
|
|
1099
|
+
self.data_inserter = DataInserter(self.conn_mgr, self.table_mgr)
|
|
1114
1100
|
|
|
1115
1101
|
@retry_on_failure(max_retries=3)
|
|
1116
1102
|
def upload_data(self, db_name: str, table_name: str,
|
|
@@ -1140,6 +1126,15 @@ class MySQLUploader:
|
|
|
1140
1126
|
:param unique_keys: 唯一约束列表(无需包含系统列)
|
|
1141
1127
|
:return: 上传结果详情
|
|
1142
1128
|
"""
|
|
1129
|
+
if db_name is None or table_name is None:
|
|
1130
|
+
logger.error('数据库名或表名不能为空', {'db_name': db_name, 'table_name': table_name})
|
|
1131
|
+
return {
|
|
1132
|
+
'success': False,
|
|
1133
|
+
'inserted_rows': 0,
|
|
1134
|
+
'skipped_rows': 0,
|
|
1135
|
+
'failed_rows': 0,
|
|
1136
|
+
'tables_created': []
|
|
1137
|
+
}
|
|
1143
1138
|
db_name = db_name.lower()
|
|
1144
1139
|
table_name = table_name.lower()
|
|
1145
1140
|
|
mdbq-4.2.5/mdbq/__version__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
VERSION = '4.2.5'
|
|
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
|
|
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
|