mdbq 3.8.14__py3-none-any.whl → 3.8.16__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/aggregation/query_data.py +0 -3
- mdbq/mysql/mysql.py +80 -73
- {mdbq-3.8.14.dist-info → mdbq-3.8.16.dist-info}/METADATA +1 -1
- {mdbq-3.8.14.dist-info → mdbq-3.8.16.dist-info}/RECORD +7 -7
- {mdbq-3.8.14.dist-info → mdbq-3.8.16.dist-info}/WHEEL +0 -0
- {mdbq-3.8.14.dist-info → mdbq-3.8.16.dist-info}/top_level.txt +0 -0
mdbq/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
VERSION = '3.8.
|
1
|
+
VERSION = '3.8.16'
|
mdbq/aggregation/query_data.py
CHANGED
@@ -3906,9 +3906,6 @@ def date_table():
|
|
3906
3906
|
table_name='日期表',
|
3907
3907
|
move_insert=True, # 先删除,再插入
|
3908
3908
|
df_sql=False, # 值为 True 时使用 df.to_sql 函数上传整个表, 不会排重
|
3909
|
-
drop_duplicates=False, # 值为 True 时检查重复数据再插入,反之直接上传,会比较慢
|
3910
|
-
count=None,
|
3911
|
-
filename=None, # 用来追踪处理进度
|
3912
3909
|
set_typ=set_typ,
|
3913
3910
|
)
|
3914
3911
|
|
mdbq/mysql/mysql.py
CHANGED
@@ -191,7 +191,7 @@ class MysqlUpload:
|
|
191
191
|
with connection.cursor() as cursor:
|
192
192
|
# 1. 查询表, 不存在则创建一个空表
|
193
193
|
sql = "SHOW TABLES LIKE %s;" # 有特殊字符不需转义
|
194
|
-
cursor.execute(sql, (table_name))
|
194
|
+
cursor.execute(sql, (table_name,))
|
195
195
|
if not cursor.fetchone():
|
196
196
|
sql = f"CREATE TABLE IF NOT EXISTS `{table_name}` (id INT AUTO_INCREMENT PRIMARY KEY);"
|
197
197
|
cursor.execute(sql)
|
@@ -201,7 +201,7 @@ class MysqlUpload:
|
|
201
201
|
dtypes, dict_data = self.cover_dict_dtypes(dict_data=dict_data) # {'店铺名称': 'varchar(100)',...}
|
202
202
|
if set_typ:
|
203
203
|
# 更新自定义的列数据类型
|
204
|
-
for k, v in dtypes.items():
|
204
|
+
for k, v in dtypes.copy().items():
|
205
205
|
# 确保传进来的 set_typ 键存在于实际的 df 列才 update
|
206
206
|
[dtypes.update({k: inside_v}) for inside_k, inside_v in set_typ.items() if k == inside_k]
|
207
207
|
|
@@ -239,48 +239,49 @@ class MysqlUpload:
|
|
239
239
|
cursor.execute(sql, (db_name, table_name))
|
240
240
|
columns = cursor.fetchall()
|
241
241
|
cols_exist = [col['COLUMN_NAME'] for col in columns] # 数据表的所有列, 返回 list
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
242
|
+
# 保留原始列名,不提前转义
|
243
|
+
raw_update_col = [item for item in cols_exist if item not in icm_update and item != 'id'] # 除了主键外的其他列
|
244
|
+
|
245
|
+
# 构建条件参数(使用原始列名)
|
246
|
+
condition_params = []
|
247
|
+
condition_parts = []
|
248
|
+
for up_col in icm_update:
|
249
|
+
condition_parts.append(f"`{up_col}` = %s") # SQL 转义
|
250
|
+
condition_params.append(dict_data[up_col]) # 原始列名用于访问数据
|
251
|
+
|
252
|
+
# 动态转义列名生成 SQL 查询字段
|
253
|
+
escaped_update_col = [f'`{col}`' for col in raw_update_col]
|
254
|
+
sql = f"""SELECT {','.join(escaped_update_col)} FROM `{table_name}` WHERE {' AND '.join(condition_parts)}"""
|
255
|
+
cursor.execute(sql, condition_params)
|
251
256
|
results = cursor.fetchall()
|
252
257
|
|
253
|
-
if results:
|
254
|
-
for result in results:
|
255
|
-
change_col = []
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
258
|
+
if results:
|
259
|
+
for result in results:
|
260
|
+
change_col = []
|
261
|
+
change_placeholders = []
|
262
|
+
set_params = []
|
263
|
+
for raw_col in raw_update_col:
|
264
|
+
# 使用原始列名访问数据
|
265
|
+
df_value = str(dict_data[raw_col])
|
266
|
+
mysql_value = str(result[raw_col])
|
267
|
+
|
268
|
+
# 清理小数点后多余的零
|
261
269
|
if '.' in df_value:
|
262
|
-
df_value = re.sub(r'0+$', '', df_value)
|
263
|
-
df_value = re.sub(r'\.$', '', df_value)
|
270
|
+
df_value = re.sub(r'0+$', '', df_value).rstrip('.')
|
264
271
|
if '.' in mysql_value:
|
265
|
-
mysql_value = re.sub(r'0+$', '', mysql_value)
|
266
|
-
|
267
|
-
if df_value != mysql_value:
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
not_change_condition = ' AND '.join([f'`{col}` = %s' for col in not_change_col])
|
279
|
-
condition += f' AND {not_change_condition}'
|
280
|
-
condition_values += [dict_data[col] for col in not_change_col]
|
281
|
-
# 执行更新
|
282
|
-
sql = f"UPDATE `{table_name}` SET {set_clause} WHERE {condition}"
|
283
|
-
cursor.execute(sql, update_values + condition_values)
|
272
|
+
mysql_value = re.sub(r'0+$', '', mysql_value).rstrip('.')
|
273
|
+
|
274
|
+
if df_value != mysql_value:
|
275
|
+
change_placeholders.append(f"`{raw_col}` = %s") # 动态转义列名
|
276
|
+
set_params.append(dict_data[raw_col])
|
277
|
+
change_col.append(raw_col)
|
278
|
+
|
279
|
+
if change_placeholders:
|
280
|
+
full_params = set_params + condition_params
|
281
|
+
sql = f"""UPDATE `{table_name}`
|
282
|
+
SET {','.join(change_placeholders)}
|
283
|
+
WHERE {' AND '.join(condition_parts)}"""
|
284
|
+
cursor.execute(sql, full_params)
|
284
285
|
else: # 没有数据返回,则直接插入数据
|
285
286
|
# 参数化插入
|
286
287
|
cols = ', '.join([f'`{k}`' for k in dict_data.keys()])
|
@@ -308,7 +309,7 @@ class MysqlUpload:
|
|
308
309
|
connection.rollback()
|
309
310
|
connection.close()
|
310
311
|
|
311
|
-
@try_except
|
312
|
+
# @try_except
|
312
313
|
def dict_to_mysql(self, db_name, table_name, dict_data, icm_update=None, index_length=100, set_typ=None, allow_not_null=False, cut_data=None):
|
313
314
|
"""
|
314
315
|
插入字典数据
|
@@ -355,7 +356,7 @@ class MysqlUpload:
|
|
355
356
|
with connection.cursor() as cursor:
|
356
357
|
# 1. 查询表, 不存在则创建一个空表
|
357
358
|
sql = "SHOW TABLES LIKE %s;" # 有特殊字符不需转义
|
358
|
-
cursor.execute(sql, (table_name))
|
359
|
+
cursor.execute(sql, (table_name,))
|
359
360
|
if not cursor.fetchone():
|
360
361
|
sql = f"CREATE TABLE IF NOT EXISTS `{table_name}` (id INT AUTO_INCREMENT PRIMARY KEY);"
|
361
362
|
cursor.execute(sql)
|
@@ -365,7 +366,7 @@ class MysqlUpload:
|
|
365
366
|
dtypes, dict_data = self.cover_dict_dtypes(dict_data=dict_data) # {'店铺名称': 'varchar(100)',...}
|
366
367
|
if set_typ:
|
367
368
|
# 更新自定义的列数据类型
|
368
|
-
for k, v in dtypes.items():
|
369
|
+
for k, v in dtypes.copy().items():
|
369
370
|
# 确保传进来的 set_typ 键存在于实际的 df 列才 update
|
370
371
|
[dtypes.update({k: inside_v}) for inside_k, inside_v in set_typ.items() if k == inside_k]
|
371
372
|
|
@@ -398,43 +399,49 @@ class MysqlUpload:
|
|
398
399
|
sql = """SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s"""
|
399
400
|
cursor.execute(sql, (db_name, table_name))
|
400
401
|
cols_exist = [col['COLUMN_NAME'] for col in cursor.fetchall()] # 数据表的所有列, 返回 list
|
401
|
-
update_col = [item for item in cols_exist if item not in icm_update and item != 'id'] # 除了主键外的其他列
|
402
402
|
|
403
|
-
#
|
403
|
+
# 保留原始列名,不提前转义
|
404
|
+
raw_update_col = [item for item in cols_exist if item not in icm_update and item != 'id']
|
405
|
+
|
406
|
+
# 构建条件参数(使用原始列名)
|
404
407
|
condition_params = []
|
405
408
|
condition_parts = []
|
406
409
|
for up_col in icm_update:
|
407
|
-
condition_parts.append(f"`{up_col}` = %s")
|
408
|
-
condition_params.append(dict_data[up_col])
|
410
|
+
condition_parts.append(f"`{up_col}` = %s") # SQL 转义
|
411
|
+
condition_params.append(dict_data[up_col]) # 原始列名访问数据
|
409
412
|
|
410
|
-
|
413
|
+
# 动态转义列名生成 SQL 查询字段
|
414
|
+
escaped_update_col = [f'`{col}`' for col in raw_update_col]
|
415
|
+
sql = f"""SELECT {','.join(escaped_update_col)} FROM `{table_name}` WHERE {' AND '.join(condition_parts)}"""
|
411
416
|
cursor.execute(sql, condition_params)
|
412
417
|
results = cursor.fetchall()
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
418
|
+
|
419
|
+
if results:
|
420
|
+
for result in results:
|
421
|
+
change_col = []
|
422
|
+
change_placeholders = []
|
423
|
+
set_params = []
|
424
|
+
for raw_col in raw_update_col:
|
425
|
+
# 使用原始列名访问数据
|
426
|
+
df_value = str(dict_data[raw_col])
|
427
|
+
mysql_value = str(result[raw_col])
|
428
|
+
|
429
|
+
# 清理小数点后多余的零
|
421
430
|
if '.' in df_value:
|
422
|
-
df_value = re.sub(r'0+$', '', df_value)
|
423
|
-
df_value = re.sub(r'\.$', '', df_value)
|
431
|
+
df_value = re.sub(r'0+$', '', df_value).rstrip('.')
|
424
432
|
if '.' in mysql_value:
|
425
|
-
mysql_value = re.sub(r'0+$', '', mysql_value)
|
426
|
-
|
427
|
-
if df_value != mysql_value:
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
if change_values: # change_values 有数据返回,表示值需要更新
|
432
|
-
set_params = [dict_data[col] for col in change_col]
|
433
|
-
full_params = set_params + condition_params # 正确顺序
|
433
|
+
mysql_value = re.sub(r'0+$', '', mysql_value).rstrip('.')
|
434
|
+
|
435
|
+
if df_value != mysql_value:
|
436
|
+
change_placeholders.append(f"`{raw_col}` = %s") # 动态转义列名
|
437
|
+
set_params.append(dict_data[raw_col])
|
438
|
+
change_col.append(raw_col)
|
434
439
|
|
440
|
+
if change_placeholders:
|
441
|
+
full_params = set_params + condition_params
|
435
442
|
sql = f"""UPDATE `{table_name}`
|
436
|
-
|
437
|
-
|
443
|
+
SET {','.join(change_placeholders)}
|
444
|
+
WHERE {' AND '.join(condition_parts)}"""
|
438
445
|
cursor.execute(sql, full_params)
|
439
446
|
else: # 没有数据返回,则直接插入数据
|
440
447
|
# 参数化插入语句
|
@@ -524,7 +531,7 @@ class MysqlUpload:
|
|
524
531
|
[pd.to_numeric(df[col], errors='ignore') for col in df.columns.tolist()]
|
525
532
|
dtypes = df.dtypes.to_dict()
|
526
533
|
__res_dict = {}
|
527
|
-
for k, v in dtypes.items():
|
534
|
+
for k, v in dtypes.copy().items():
|
528
535
|
result1 = re.findall(r'编码|_?id|货号|款号|文件大小', k, re.IGNORECASE)
|
529
536
|
result2 = re.findall(r'占比$|投产$|产出$|roi$|率$', k, re.IGNORECASE)
|
530
537
|
result3 = re.findall(r'同比$|环比$', k, re.IGNORECASE)
|
@@ -611,7 +618,7 @@ class MysqlUpload:
|
|
611
618
|
dtypes, df = self.convert_df_dtypes(df)
|
612
619
|
if set_typ:
|
613
620
|
# 更新自定义的列数据类型
|
614
|
-
for k, v in dtypes.items():
|
621
|
+
for k, v in dtypes.copy().items():
|
615
622
|
# 确保传进来的 set_typ 键存在于实际的 df 列才 update
|
616
623
|
[dtypes.update({k: inside_v}) for inside_k, inside_v in set_typ.items() if k == inside_k]
|
617
624
|
|
@@ -635,7 +642,7 @@ class MysqlUpload:
|
|
635
642
|
with connection.cursor() as cursor:
|
636
643
|
# 1. 查询表, 不存在则创建一个空表
|
637
644
|
sql = "SHOW TABLES LIKE %s;" # 有特殊字符不需转义
|
638
|
-
cursor.execute(sql, (table_name))
|
645
|
+
cursor.execute(sql, (table_name,))
|
639
646
|
if not cursor.fetchone():
|
640
647
|
create_table_sql = f"CREATE TABLE IF NOT EXISTS `{table_name}` (id INT AUTO_INCREMENT PRIMARY KEY)"
|
641
648
|
cursor.execute(create_table_sql)
|
@@ -661,7 +668,7 @@ class MysqlUpload:
|
|
661
668
|
# 创建索引
|
662
669
|
if col == '日期':
|
663
670
|
sql = f"SHOW INDEXES FROM `{table_name}` WHERE `Column_name` = %s"
|
664
|
-
cursor.execute(sql, (col))
|
671
|
+
cursor.execute(sql, (col,))
|
665
672
|
result = cursor.fetchone() # 检查索引是否存在
|
666
673
|
if not result:
|
667
674
|
cursor.execute(f"CREATE INDEX index_name ON `{table_name}`(`{col}`)")
|
@@ -1,13 +1,13 @@
|
|
1
1
|
mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
|
2
|
-
mdbq/__version__.py,sha256=
|
2
|
+
mdbq/__version__.py,sha256=VUh6syxyz3BeTHjQrrlUgLdyX1-2SRQdP5locYySmCQ,18
|
3
3
|
mdbq/aggregation/__init__.py,sha256=EeDqX2Aml6SPx8363J-v1lz0EcZtgwIBYyCJV6CcEDU,40
|
4
|
-
mdbq/aggregation/query_data.py,sha256=
|
4
|
+
mdbq/aggregation/query_data.py,sha256=5_OzjGR5Sq00q-EgAYmSE5V9i4Solw9y4hkldl4mvt8,179808
|
5
5
|
mdbq/config/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
|
6
6
|
mdbq/config/config.py,sha256=eaTfrfXQ65xLqjr5I8-HkZd_jEY1JkGinEgv3TSLeoQ,3170
|
7
7
|
mdbq/log/__init__.py,sha256=Mpbrav0s0ifLL7lVDAuePEi1hJKiSHhxcv1byBKDl5E,15
|
8
8
|
mdbq/log/spider_logging.py,sha256=-ozWWEGm3HVv604ozs_OOvVwumjokmUPwbaodesUrPY,1664
|
9
9
|
mdbq/mysql/__init__.py,sha256=A_DPJyAoEvTSFojiI2e94zP0FKtCkkwKP1kYUCSyQzo,11
|
10
|
-
mdbq/mysql/mysql.py,sha256=
|
10
|
+
mdbq/mysql/mysql.py,sha256=4N6srlRYomoSHdK4Y84fxkIW_eL5xFkb3Jo06sebSi0,55031
|
11
11
|
mdbq/mysql/s_query.py,sha256=X055aLRAgxVvueXx4NbfNjp6MyBI02_XBb1pTKw09L0,8660
|
12
12
|
mdbq/other/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
|
13
13
|
mdbq/other/download_sku_picture.py,sha256=YU8DxKMXbdeE1OOKEA848WVp62jYHw5O4tXTjUdq9H0,44832
|
@@ -21,7 +21,7 @@ mdbq/redis/__init__.py,sha256=YtgBlVSMDphtpwYX248wGge1x-Ex_mMufz4-8W0XRmA,12
|
|
21
21
|
mdbq/redis/getredis.py,sha256=Uk8-cOWT0JU1qRyIVqdbYokSLvkDIAfcokmYj1ebw8k,24104
|
22
22
|
mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
|
23
23
|
mdbq/spider/aikucun.py,sha256=m7ZIvrc9pqoGCYEH3FtgKTwqhX7QB6qzgc2twDzhX4w,19962
|
24
|
-
mdbq-3.8.
|
25
|
-
mdbq-3.8.
|
26
|
-
mdbq-3.8.
|
27
|
-
mdbq-3.8.
|
24
|
+
mdbq-3.8.16.dist-info/METADATA,sha256=TS9KZw82-cE9gTPtfKSLzhwWzda-8ZnZ6384Vm0xU4I,364
|
25
|
+
mdbq-3.8.16.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
26
|
+
mdbq-3.8.16.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
|
27
|
+
mdbq-3.8.16.dist-info/RECORD,,
|
File without changes
|
File without changes
|