mdbq 4.1.13__py3-none-any.whl → 4.1.14__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.
Potentially problematic release.
This version of mdbq might be problematic. Click here for more details.
- mdbq/__version__.py +1 -1
- mdbq/mysql/uploader.py +121 -171
- {mdbq-4.1.13.dist-info → mdbq-4.1.14.dist-info}/METADATA +1 -1
- {mdbq-4.1.13.dist-info → mdbq-4.1.14.dist-info}/RECORD +6 -6
- {mdbq-4.1.13.dist-info → mdbq-4.1.14.dist-info}/WHEEL +0 -0
- {mdbq-4.1.13.dist-info → mdbq-4.1.14.dist-info}/top_level.txt +0 -0
mdbq/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
VERSION = '4.1.
|
|
1
|
+
VERSION = '4.1.14'
|
mdbq/mysql/uploader.py
CHANGED
|
@@ -1362,79 +1362,60 @@ class MySQLUploader:
|
|
|
1362
1362
|
# 跳过id列,不允许外部传入id
|
|
1363
1363
|
if (self.case_sensitive and col_name == 'id') or (not self.case_sensitive and col_name.lower() == 'id'):
|
|
1364
1364
|
continue
|
|
1365
|
-
#
|
|
1365
|
+
# 对于自动时间戳字段,跳过处理,让MySQL自动处理
|
|
1366
1366
|
col_type_lower = filtered_set_typ[col_name].lower()
|
|
1367
1367
|
is_auto_timestamp = ('timestamp' in col_type_lower and 'current_timestamp' in col_type_lower and
|
|
1368
1368
|
col_name in ['创建时间', '更新时间'])
|
|
1369
1369
|
|
|
1370
|
+
if is_auto_timestamp:
|
|
1371
|
+
# 自动时间戳字段完全跳过,不在INSERT语句中包含
|
|
1372
|
+
continue
|
|
1373
|
+
|
|
1370
1374
|
if col_name not in row:
|
|
1371
1375
|
# 对于缺失的列,使用None作为默认值,在_validate_value中会根据allow_null和列类型进行进一步处理
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
if fallback_value is not None:
|
|
1384
|
-
prepared_row[col_name] = fallback_value
|
|
1385
|
-
logger.warning(f"行号:{row_idx} -> 缺失列: `{col_name}`, 使用兜底值: {fallback_value}", {'row': self._shorten_for_log(row)})
|
|
1386
|
-
else:
|
|
1387
|
-
error_msg = f"行号:{row_idx} -> 缺失列: `{col_name}`, 且不允许空值"
|
|
1388
|
-
logger.error(error_msg, {'row': self._shorten_for_log(row)})
|
|
1389
|
-
raise ValueError(error_msg)
|
|
1390
|
-
except Exception:
|
|
1376
|
+
try:
|
|
1377
|
+
prepared_row[col_name] = self._validate_value(None, filtered_set_typ[col_name], allow_null, db_name, table_name, col_name)
|
|
1378
|
+
except ValueError as e:
|
|
1379
|
+
if not allow_null:
|
|
1380
|
+
# 如果不允许空值但验证失败,尝试使用兜底值
|
|
1381
|
+
try:
|
|
1382
|
+
fallback_value = self._get_fallback_value(filtered_set_typ[col_name].lower(), allow_null, db_name, table_name, col_name, None)
|
|
1383
|
+
if fallback_value is not None:
|
|
1384
|
+
prepared_row[col_name] = fallback_value
|
|
1385
|
+
logger.warning(f"行号:{row_idx} -> 缺失列: `{col_name}`, 使用兜底值: {fallback_value}", {'row': self._shorten_for_log(row)})
|
|
1386
|
+
else:
|
|
1391
1387
|
error_msg = f"行号:{row_idx} -> 缺失列: `{col_name}`, 且不允许空值"
|
|
1392
1388
|
logger.error(error_msg, {'row': self._shorten_for_log(row)})
|
|
1393
1389
|
raise ValueError(error_msg)
|
|
1394
|
-
|
|
1395
|
-
|
|
1390
|
+
except Exception:
|
|
1391
|
+
error_msg = f"行号:{row_idx} -> 缺失列: `{col_name}`, 且不允许空值"
|
|
1392
|
+
logger.error(error_msg, {'row': self._shorten_for_log(row)})
|
|
1393
|
+
raise ValueError(error_msg)
|
|
1394
|
+
else:
|
|
1395
|
+
prepared_row[col_name] = None
|
|
1396
1396
|
else:
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
prepared_row[col_name] =
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
if is_empty_original and not allow_null:
|
|
1420
|
-
try:
|
|
1421
|
-
fallback_value = self._get_fallback_value(filtered_set_typ[col_name].lower(), allow_null, db_name, table_name, col_name, original_value)
|
|
1422
|
-
if fallback_value is not None:
|
|
1423
|
-
prepared_row[col_name] = fallback_value
|
|
1424
|
-
logger.warning(f"行:{row_idx}, 列:`{col_name}` -> 原值验证失败,使用兜底值: {fallback_value}", {
|
|
1425
|
-
'原值': original_value,
|
|
1426
|
-
'兜底值': fallback_value,
|
|
1427
|
-
'row': self._shorten_for_log(row)
|
|
1428
|
-
})
|
|
1429
|
-
else:
|
|
1430
|
-
logger.error('数据验证失败', {
|
|
1431
|
-
'列': col_name,
|
|
1432
|
-
'行': row_idx,
|
|
1433
|
-
'报错': str(e),
|
|
1434
|
-
'row': self._shorten_for_log(row),
|
|
1435
|
-
})
|
|
1436
|
-
raise ValueError(f"行:{row_idx}, 列:`{col_name}`-> 报错: {str(e)}")
|
|
1437
|
-
except Exception:
|
|
1397
|
+
# 处理用户传入的值
|
|
1398
|
+
try:
|
|
1399
|
+
prepared_row[col_name] = self._validate_value(row[col_name], filtered_set_typ[col_name], allow_null, db_name, table_name, col_name)
|
|
1400
|
+
except ValueError as e:
|
|
1401
|
+
# 如果数据验证失败,检查是否为空值且不允许空值,尝试使用兜底值
|
|
1402
|
+
original_value = row[col_name]
|
|
1403
|
+
is_empty_original = (original_value is None or
|
|
1404
|
+
original_value == '' or
|
|
1405
|
+
(not isinstance(original_value, (list, dict)) and
|
|
1406
|
+
pd.isna(original_value) if hasattr(pd, 'isna') else False))
|
|
1407
|
+
|
|
1408
|
+
if is_empty_original and not allow_null:
|
|
1409
|
+
try:
|
|
1410
|
+
fallback_value = self._get_fallback_value(filtered_set_typ[col_name].lower(), allow_null, db_name, table_name, col_name, original_value)
|
|
1411
|
+
if fallback_value is not None:
|
|
1412
|
+
prepared_row[col_name] = fallback_value
|
|
1413
|
+
logger.warning(f"行:{row_idx}, 列:`{col_name}` -> 原值验证失败,使用兜底值: {fallback_value}", {
|
|
1414
|
+
'原值': original_value,
|
|
1415
|
+
'兜底值': fallback_value,
|
|
1416
|
+
'row': self._shorten_for_log(row)
|
|
1417
|
+
})
|
|
1418
|
+
else:
|
|
1438
1419
|
logger.error('数据验证失败', {
|
|
1439
1420
|
'列': col_name,
|
|
1440
1421
|
'行': row_idx,
|
|
@@ -1442,7 +1423,7 @@ class MySQLUploader:
|
|
|
1442
1423
|
'row': self._shorten_for_log(row),
|
|
1443
1424
|
})
|
|
1444
1425
|
raise ValueError(f"行:{row_idx}, 列:`{col_name}`-> 报错: {str(e)}")
|
|
1445
|
-
|
|
1426
|
+
except Exception:
|
|
1446
1427
|
logger.error('数据验证失败', {
|
|
1447
1428
|
'列': col_name,
|
|
1448
1429
|
'行': row_idx,
|
|
@@ -1450,6 +1431,14 @@ class MySQLUploader:
|
|
|
1450
1431
|
'row': self._shorten_for_log(row),
|
|
1451
1432
|
})
|
|
1452
1433
|
raise ValueError(f"行:{row_idx}, 列:`{col_name}`-> 报错: {str(e)}")
|
|
1434
|
+
else:
|
|
1435
|
+
logger.error('数据验证失败', {
|
|
1436
|
+
'列': col_name,
|
|
1437
|
+
'行': row_idx,
|
|
1438
|
+
'报错': str(e),
|
|
1439
|
+
'row': self._shorten_for_log(row),
|
|
1440
|
+
})
|
|
1441
|
+
raise ValueError(f"行:{row_idx}, 列:`{col_name}`-> 报错: {str(e)}")
|
|
1453
1442
|
prepared_data.append(prepared_row)
|
|
1454
1443
|
return prepared_data, filtered_set_typ
|
|
1455
1444
|
|
|
@@ -1899,8 +1888,17 @@ class MySQLUploader:
|
|
|
1899
1888
|
cached = self._prepared_statements.get(cache_key)
|
|
1900
1889
|
if cached:
|
|
1901
1890
|
return cached
|
|
1902
|
-
# 获取所有列名(排除id
|
|
1903
|
-
all_columns = [
|
|
1891
|
+
# 获取所有列名(排除id和自动时间戳字段)
|
|
1892
|
+
all_columns = []
|
|
1893
|
+
for col in set_typ.keys():
|
|
1894
|
+
if col.lower() == 'id':
|
|
1895
|
+
continue
|
|
1896
|
+
# 检查是否是自动时间戳字段
|
|
1897
|
+
col_type_lower = set_typ[col].lower()
|
|
1898
|
+
is_auto_timestamp = ('timestamp' in col_type_lower and 'current_timestamp' in col_type_lower and
|
|
1899
|
+
col in ['创建时间', '更新时间'])
|
|
1900
|
+
if not is_auto_timestamp:
|
|
1901
|
+
all_columns.append(col)
|
|
1904
1902
|
if not check_duplicate:
|
|
1905
1903
|
sql = self._build_simple_insert_sql(db_name, table_name, all_columns,
|
|
1906
1904
|
update_on_duplicate)
|
|
@@ -1956,51 +1954,19 @@ class MySQLUploader:
|
|
|
1956
1954
|
return str(value)
|
|
1957
1955
|
return value
|
|
1958
1956
|
|
|
1959
|
-
def execute_single_row_with_defaults(row):
|
|
1960
|
-
"""处理单行插入,支持DEFAULT字段"""
|
|
1961
|
-
has_defaults = any(row.get(col) == 'DEFAULT' for col in all_columns)
|
|
1962
|
-
|
|
1963
|
-
if has_defaults:
|
|
1964
|
-
# 分离普通字段和DEFAULT字段
|
|
1965
|
-
regular_columns = []
|
|
1966
|
-
regular_values = []
|
|
1967
|
-
default_columns = []
|
|
1968
|
-
|
|
1969
|
-
for col in all_columns:
|
|
1970
|
-
val = row.get(col)
|
|
1971
|
-
if val == 'DEFAULT':
|
|
1972
|
-
default_columns.append(col)
|
|
1973
|
-
else:
|
|
1974
|
-
regular_columns.append(col)
|
|
1975
|
-
regular_values.append(ensure_basic_type(val))
|
|
1976
|
-
|
|
1977
|
-
# 构建INSERT ... SET语句
|
|
1978
|
-
set_clauses = []
|
|
1979
|
-
for col in regular_columns:
|
|
1980
|
-
set_clauses.append(f"`{self._validate_identifier(col)}` = %s")
|
|
1981
|
-
for col in default_columns:
|
|
1982
|
-
set_clauses.append(f"`{self._validate_identifier(col)}` = DEFAULT")
|
|
1983
|
-
|
|
1984
|
-
if set_clauses:
|
|
1985
|
-
dynamic_sql = f"INSERT INTO `{db_name}`.`{table_name}` SET {', '.join(set_clauses)}"
|
|
1986
|
-
if update_on_duplicate and regular_columns:
|
|
1987
|
-
update_clauses = [f"`{self._validate_identifier(col)}` = VALUES(`{self._validate_identifier(col)}`)" for col in regular_columns]
|
|
1988
|
-
if update_clauses:
|
|
1989
|
-
dynamic_sql += f" ON DUPLICATE KEY UPDATE {', '.join(update_clauses)}"
|
|
1990
|
-
|
|
1991
|
-
cursor.execute(dynamic_sql, regular_values)
|
|
1992
|
-
return cursor.rowcount if cursor.rowcount is not None else 0
|
|
1993
|
-
else:
|
|
1994
|
-
# 没有DEFAULT字段,使用原有逻辑
|
|
1995
|
-
values = [ensure_basic_type(row.get(col)) for col in all_columns]
|
|
1996
|
-
if check_duplicate and not update_on_duplicate:
|
|
1997
|
-
dup_cols = duplicate_columns if duplicate_columns else [col for col in all_columns if col.lower() not in self.base_excute_col]
|
|
1998
|
-
values += [ensure_basic_type(row.get(col)) for col in dup_cols]
|
|
1999
|
-
cursor.execute(sql, values)
|
|
2000
|
-
return cursor.rowcount if cursor.rowcount is not None else 0
|
|
2001
1957
|
|
|
2002
1958
|
batch_size = get_optimal_batch_size(len(data))
|
|
2003
|
-
|
|
1959
|
+
# 排除id列和自动时间戳列
|
|
1960
|
+
all_columns = []
|
|
1961
|
+
for col in set_typ.keys():
|
|
1962
|
+
if col.lower() == 'id':
|
|
1963
|
+
continue
|
|
1964
|
+
# 检查是否是自动时间戳字段
|
|
1965
|
+
col_type_lower = set_typ[col].lower()
|
|
1966
|
+
is_auto_timestamp = ('timestamp' in col_type_lower and 'current_timestamp' in col_type_lower and
|
|
1967
|
+
col in ['创建时间', '更新时间'])
|
|
1968
|
+
if not is_auto_timestamp:
|
|
1969
|
+
all_columns.append(col)
|
|
2004
1970
|
total_inserted = 0
|
|
2005
1971
|
total_skipped = 0
|
|
2006
1972
|
total_failed = 0
|
|
@@ -2009,72 +1975,51 @@ class MySQLUploader:
|
|
|
2009
1975
|
if transaction_mode == 'batch':
|
|
2010
1976
|
for i in range(0, len(data), batch_size):
|
|
2011
1977
|
batch = data[i:i + batch_size]
|
|
2012
|
-
#
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
else:
|
|
2023
|
-
if affected > 0:
|
|
2024
|
-
total_inserted += 1
|
|
2025
|
-
else:
|
|
2026
|
-
total_skipped += 1
|
|
2027
|
-
except pymysql.err.IntegrityError:
|
|
2028
|
-
total_skipped += 1
|
|
2029
|
-
except Exception as e:
|
|
2030
|
-
total_failed += 1
|
|
2031
|
-
logger.error('单行插入失败', {
|
|
2032
|
-
'库': db_name,
|
|
2033
|
-
'表': table_name,
|
|
2034
|
-
'错误': str(e)
|
|
2035
|
-
})
|
|
1978
|
+
# 使用批量插入逻辑
|
|
1979
|
+
values_list = []
|
|
1980
|
+
for row in batch:
|
|
1981
|
+
values = [ensure_basic_type(row.get(col)) for col in all_columns]
|
|
1982
|
+
if check_duplicate and not update_on_duplicate:
|
|
1983
|
+
dup_cols = duplicate_columns if duplicate_columns else [col for col in all_columns if col.lower() not in self.base_excute_col]
|
|
1984
|
+
values += [ensure_basic_type(row.get(col)) for col in dup_cols]
|
|
1985
|
+
values_list.append(values)
|
|
1986
|
+
try:
|
|
1987
|
+
cursor.executemany(sql, values_list)
|
|
2036
1988
|
conn.commit()
|
|
2037
|
-
|
|
2038
|
-
#
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
# 当不启用更新时,affected_rows只包含插入的行数
|
|
2060
|
-
total_inserted += affected
|
|
2061
|
-
total_skipped += len(batch) - affected
|
|
2062
|
-
except pymysql.err.IntegrityError as e:
|
|
2063
|
-
conn.rollback()
|
|
2064
|
-
# 在唯一约束冲突时,所有行都被跳过
|
|
2065
|
-
total_skipped += len(batch)
|
|
2066
|
-
logger.debug('批量插入唯一约束冲突,全部跳过', {'库': db_name, '表': table_name, '错误': str(e)})
|
|
2067
|
-
except Exception as e:
|
|
2068
|
-
conn.rollback()
|
|
2069
|
-
total_failed += len(batch)
|
|
2070
|
-
logger.error('批量插入失败', {'库': db_name, '表': table_name, '错误': str(e)})
|
|
1989
|
+
# 在batch模式下,affected_rows表示实际影响的行数
|
|
1990
|
+
# 如果update_on_duplicate为True,则affected_rows包含更新的行数
|
|
1991
|
+
# 如果update_on_duplicate为False,则affected_rows只包含插入的行数
|
|
1992
|
+
affected = cursor.rowcount if cursor.rowcount is not None else 0
|
|
1993
|
+
if update_on_duplicate:
|
|
1994
|
+
# 当启用更新时,affected_rows包含插入和更新的行数
|
|
1995
|
+
# 我们需要区分插入和更新的行数
|
|
1996
|
+
# 由于无法准确区分,我们假设所有行都是插入的
|
|
1997
|
+
total_inserted += len(batch)
|
|
1998
|
+
else:
|
|
1999
|
+
# 当不启用更新时,affected_rows只包含插入的行数
|
|
2000
|
+
total_inserted += affected
|
|
2001
|
+
total_skipped += len(batch) - affected
|
|
2002
|
+
except pymysql.err.IntegrityError as e:
|
|
2003
|
+
conn.rollback()
|
|
2004
|
+
# 在唯一约束冲突时,所有行都被跳过
|
|
2005
|
+
total_skipped += len(batch)
|
|
2006
|
+
logger.debug('批量插入唯一约束冲突,全部跳过', {'库': db_name, '表': table_name, '错误': str(e)})
|
|
2007
|
+
except Exception as e:
|
|
2008
|
+
conn.rollback()
|
|
2009
|
+
total_failed += len(batch)
|
|
2010
|
+
logger.error('批量插入失败', {'库': db_name, '表': table_name, '错误': str(e)})
|
|
2071
2011
|
elif transaction_mode == 'hybrid':
|
|
2072
2012
|
hybrid_n = 100 # 可配置
|
|
2073
2013
|
for i in range(0, len(data), hybrid_n):
|
|
2074
2014
|
batch = data[i:i + hybrid_n]
|
|
2075
2015
|
for row in batch:
|
|
2076
2016
|
try:
|
|
2077
|
-
|
|
2017
|
+
values = [ensure_basic_type(row.get(col)) for col in all_columns]
|
|
2018
|
+
if check_duplicate and not update_on_duplicate:
|
|
2019
|
+
dup_cols = duplicate_columns if duplicate_columns else [col for col in all_columns if col.lower() not in self.base_excute_col]
|
|
2020
|
+
values += [ensure_basic_type(row.get(col)) for col in dup_cols]
|
|
2021
|
+
cursor.execute(sql, values)
|
|
2022
|
+
affected = cursor.rowcount if cursor.rowcount is not None else 0
|
|
2078
2023
|
if update_on_duplicate:
|
|
2079
2024
|
# 当启用更新时,affected_rows包含插入和更新的行数
|
|
2080
2025
|
# 假设所有行都是插入的,因为无法区分插入和更新
|
|
@@ -2097,7 +2042,12 @@ class MySQLUploader:
|
|
|
2097
2042
|
else: # row模式
|
|
2098
2043
|
for row in data:
|
|
2099
2044
|
try:
|
|
2100
|
-
|
|
2045
|
+
values = [ensure_basic_type(row.get(col)) for col in all_columns]
|
|
2046
|
+
if check_duplicate and not update_on_duplicate:
|
|
2047
|
+
dup_cols = duplicate_columns if duplicate_columns else [col for col in all_columns if col.lower() not in self.base_excute_col]
|
|
2048
|
+
values += [ensure_basic_type(row.get(col)) for col in dup_cols]
|
|
2049
|
+
cursor.execute(sql, values)
|
|
2050
|
+
affected = cursor.rowcount if cursor.rowcount is not None else 0
|
|
2101
2051
|
if update_on_duplicate:
|
|
2102
2052
|
# 当启用更新时,affected_rows包含插入和更新的行数
|
|
2103
2053
|
# 假设所有行都是插入的,因为无法区分插入和更新
|
|
@@ -2737,9 +2687,9 @@ class MySQLUploader:
|
|
|
2737
2687
|
|
|
2738
2688
|
# 使用MySQL的CURRENT_TIMESTAMP功能,按固定顺序添加时间戳列
|
|
2739
2689
|
# 创建时间:插入时自动设置,更新时不变
|
|
2740
|
-
updated_set_typ[created_col] = 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP'
|
|
2690
|
+
updated_set_typ[created_col] = 'TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP'
|
|
2741
2691
|
# 更新时间:插入和更新时都自动设置为当前时间
|
|
2742
|
-
updated_set_typ[updated_col] = 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'
|
|
2692
|
+
updated_set_typ[updated_col] = 'TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'
|
|
2743
2693
|
|
|
2744
2694
|
# 处理DataFrame格式的数据
|
|
2745
2695
|
if hasattr(data, 'shape') and hasattr(data, 'columns'):
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
|
|
2
|
-
mdbq/__version__.py,sha256=
|
|
2
|
+
mdbq/__version__.py,sha256=zj2uAJqL04jV1wMjxAyT-2T4sjHxXiGCOfNFXJfgjz0,18
|
|
3
3
|
mdbq/auth/__init__.py,sha256=pnPMAt63sh1B6kEvmutUuro46zVf2v2YDAG7q-jV_To,24
|
|
4
4
|
mdbq/auth/auth_backend.py,sha256=iLN7AqiSq7fQgFtNtge_TIlVOR1hrCSZXH6oId6uGX4,116924
|
|
5
5
|
mdbq/auth/crypto.py,sha256=fcZRFCnrKVVdWDUx_zds51ynFYwS9DBvJOrRQVldrfM,15931
|
|
@@ -15,7 +15,7 @@ mdbq/mysql/deduplicator.py,sha256=tzLIm9K9S0lGLlVTI0dDQVYpWX796XCuyufmw1lU26Y,73
|
|
|
15
15
|
mdbq/mysql/mysql.py,sha256=pDg771xBugCMSTWeskIFTi3pFLgaqgyG3smzf-86Wn8,56772
|
|
16
16
|
mdbq/mysql/s_query.py,sha256=N2xHJf2CiUXjXIVBemdst-wamIP3908EGAJOFG13fCU,50475
|
|
17
17
|
mdbq/mysql/unique_.py,sha256=MaztT-WIyEQUs-OOYY4pFulgHVcXR1BfCy3QUz0XM_U,21127
|
|
18
|
-
mdbq/mysql/uploader.py,sha256=
|
|
18
|
+
mdbq/mysql/uploader.py,sha256=5zpvcQpa1BAtFKkVF-EQYXSieeF2hHoZQq6lmEaEnjY,133474
|
|
19
19
|
mdbq/other/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
|
|
20
20
|
mdbq/other/download_sku_picture.py,sha256=X66sVdvVgzoNzmgVJyPtd7bjEvctEKtLPblEPF65EWc,46940
|
|
21
21
|
mdbq/other/error_handler.py,sha256=4p5haAXSY-P78stp4Xwo_MwAngWYqyKj5ogWIuYXMeY,12631
|
|
@@ -35,7 +35,7 @@ mdbq/route/routes.py,sha256=QVGfTvDgu0CpcKCvk1ra74H8uojgqTLUav1fnVAqLEA,29433
|
|
|
35
35
|
mdbq/selenium/__init__.py,sha256=AKzeEceqZyvqn2dEDoJSzDQnbuENkJSHAlbHAD0u0ZI,10
|
|
36
36
|
mdbq/selenium/get_driver.py,sha256=1NTlVUE6QsyjTrVVVqTO2LOnYf578ccFWlWnvIXGtic,20903
|
|
37
37
|
mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
|
|
38
|
-
mdbq-4.1.
|
|
39
|
-
mdbq-4.1.
|
|
40
|
-
mdbq-4.1.
|
|
41
|
-
mdbq-4.1.
|
|
38
|
+
mdbq-4.1.14.dist-info/METADATA,sha256=KTtSRhxxSKyWNWlEvHI7YIhD6XDneGbuEw3Qa1ku5EE,364
|
|
39
|
+
mdbq-4.1.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
40
|
+
mdbq-4.1.14.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
|
|
41
|
+
mdbq-4.1.14.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|