cppackage 0.2.9__py3-none-any.whl → 0.3.1__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.
CPpackage/db/sql_model.py CHANGED
@@ -1,8 +1,6 @@
1
1
  import pymysql
2
2
  import time
3
3
  from pymysql import Error
4
- import pandas as pd
5
- # 条件导入:支持直接运行和包模式
6
4
  try:
7
5
  from .config import get_db_config
8
6
  except (ImportError, ValueError):
@@ -161,6 +159,13 @@ def find_duplicate_records(table_name, database, unique_index_fields, port=None)
161
159
  """
162
160
 
163
161
  try:
162
+ # Lazy import pandas here to avoid heavy imports during module import
163
+ try:
164
+ import pandas as pd
165
+ except Exception as e:
166
+ print("无法导入 pandas:", e)
167
+ return None
168
+
164
169
  with _get_connection(database, port) as conn:
165
170
  df_duplicates = pd.read_sql(sql, conn)
166
171
  if df_duplicates.empty:
@@ -168,8 +173,8 @@ def find_duplicate_records(table_name, database, unique_index_fields, port=None)
168
173
  else:
169
174
  print(f"发现 {len(df_duplicates)} 条重复记录({len(df_duplicates.drop_duplicates(subset=unique_index_fields))} 组重复组合)")
170
175
  # 可选:保存重复记录到CSV
171
- df_duplicates.to_csv(f"duplicate_records_{table_name}.csv", index=False, encoding="utf-8-sig")
172
- print("重复记录已保存到 duplicate_records_{table_name}.csv")
176
+ # df_duplicates.to_csv(f"duplicate_records_{table_name}.csv", index=False, encoding="utf-8-sig")
177
+ # print("重复记录已保存到 duplicate_records_{table_name}.csv")
173
178
  return df_duplicates
174
179
  except pymysql.MySQLError as e:
175
180
  print("数据库查询失败:", e)
@@ -178,7 +183,7 @@ def find_duplicate_records(table_name, database, unique_index_fields, port=None)
178
183
  print("未知错误:", e)
179
184
  return None
180
185
  # ===================== 删除重复记录函数(修复参数+调用逻辑) =====================
181
- def delete_duplicate_records(table_name, database, unique_index_fields, port=None, keep_strategy="min_id"):
186
+ def delete_duplicate_records(table_name, database, unique_index_fields, port=None, keep_strategy="max_id"):
182
187
  """
183
188
  删除重复记录,仅保留每组唯一值的一条记录
184
189
  参数:
@@ -190,10 +195,6 @@ def delete_duplicate_records(table_name, database, unique_index_fields, port=Non
190
195
  返回:
191
196
  int: 删除的记录数;None: 出错;0: 无重复
192
197
  """
193
- # 1. 先调用修复后的find_duplicate_records查询重复数据
194
- duplicate_df = find_duplicate_records(table_name, database, unique_index_fields, port)
195
- if duplicate_df is None or duplicate_df.empty:
196
- return 0
197
198
 
198
199
  # 2. 构建删除SQL(核心逻辑)
199
200
  group_by_str = ",".join([f"`{field}`" for field in unique_index_fields])
@@ -243,43 +244,51 @@ def delete_duplicate_records(table_name, database, unique_index_fields, port=Non
243
244
  return None
244
245
  # ===================== DataFrame 入库 =====================
245
246
 
246
- def update_datas(df, table_name, database):
247
-
248
- conn = None
249
- for i in range(2):
250
- try:
251
- conn = _get_connection(database)
252
- cursor = conn.cursor()
253
- cols = list(df.columns)
254
- col_str = ",".join([f"`{c}`" for c in cols])
255
- value_tpl = "(" + ",".join(["%s"] * len(cols)) + ")"
256
- values_str = ",".join([value_tpl] * len(df))
257
- update_clause = ",".join(
258
- [f"`{c}`=VALUES(`{c}`)" for c in cols if c != "id"]
259
- )
260
- sql = f"""
261
- INSERT INTO `{table_name}` ({col_str})
262
- VALUES {values_str}
263
- ON DUPLICATE KEY UPDATE {update_clause}
264
- """
265
- print(sql)
266
- data = [tuple(row) for row in df.values]
267
- flat_data = [v for row in data for v in row]
268
- cursor.execute(sql, flat_data)
269
- conn.commit()
270
- print(f"成功插入/更新 {cursor.rowcount} 条记录")
271
- break
272
- except Exception as e:
273
- if conn:
274
- conn.rollback()
275
- print("入库失败:", e)
276
- if '1054, "Unknown column' in str(e):
277
- # 表结构校验,df为抓取数据表
278
- check_and_sync_columns(df,table_name,database)
279
- else:
280
- raise Exception(e)
281
- finally:
282
- if conn:
283
- conn.close()
247
+ def update_datas(df, table_name, database, batch_size=20):
284
248
 
249
+ if df.empty:
250
+ print("数据为空,无需入库")
251
+ return
252
+ cols = list(df.columns)
253
+ col_str = ",".join([f"`{c}`" for c in cols])
254
+ value_tpl = "(" + ",".join(["%s"] * len(cols)) + ")"
255
+ update_clause = ",".join(
256
+ [f"`{c}`=VALUES(`{c}`)" for c in cols if c != "id"]
257
+ )
258
+ total = len(df)
259
+ success_count = 0
260
+ for start in range(0, total, batch_size):
261
+ batch_df = df.iloc[start:start + batch_size]
262
+ values_str = ",".join([value_tpl] * len(batch_df))
263
+ sql = f"""
264
+ INSERT INTO `{table_name}` ({col_str})
265
+ VALUES {values_str}
266
+ ON DUPLICATE KEY UPDATE {update_clause}
267
+ """
268
+ data = [tuple(row) for row in batch_df.values]
269
+ flat_data = [v for row in data for v in row]
270
+ conn = None
271
+ for attempt in range(2):
272
+ try:
273
+ conn = _get_connection(database)
274
+ cursor = conn.cursor()
275
+ cursor.execute(sql, flat_data)
276
+ conn.commit()
277
+ success_count += cursor.rowcount
278
+ break
279
+ except Exception as e:
280
+ if conn:
281
+ conn.rollback()
282
+ print(f"批次入库失败(start={start}):", e)
283
+ if '1054, "Unknown column' in str(e):
284
+ check_and_sync_columns(df, table_name, database)
285
+ break
286
+ elif attempt == 0:
287
+ time.sleep(1)
288
+ else:
289
+ raise Exception(e)
290
+ finally:
291
+ if conn:
292
+ conn.close()
293
+ print(f"成功插入/更新 {success_count} 条记录")
285
294
 
CPpackage/db/test.py CHANGED
@@ -4,21 +4,22 @@ import os
4
4
 
5
5
  if __name__ == "__main__":
6
6
  # 配置你的参数
7
- TABLE_NAME = "pinlei_hgjk" # 替换为实际表名
8
- DATABASE_NAME = "shengyicanmou_copy" # 替换为实际数据库名
7
+ TABLE_NAME = "pinlei_spph"
8
+ DATABASE_NAME = "shengyicanmou"
9
9
  # 你的唯一索引字段列表(必须是列表类型!)
10
- UNIQUE_FIELDS = ['begindate', 'enddate', 'value_l', 'sellerId', 'statDate', 'date_effect', 'store_id']
10
+ UNIQUE_FIELDS = ["itemId", "store_id", "begindate", "value_l", "sellerId", "cateLevel2Id", "cateId", "cateLevel1Id", "mainProductId", "itemTag", "date_effect"]
11
11
  PORT = 3306 # 可选,默认从配置获取
12
12
 
13
13
  # 第一步:查询重复记录
14
14
  dup_df = find_duplicate_records(TABLE_NAME, DATABASE_NAME, UNIQUE_FIELDS, PORT)
15
15
 
16
- # 第二步:确认有重复后删除
16
+ # # 第二步:确认有重复后删除
17
17
  if dup_df is not None and not dup_df.empty:
18
+
18
19
  delete_count = delete_duplicate_records(
19
20
  table_name=TABLE_NAME,
20
21
  database=DATABASE_NAME,
21
22
  unique_index_fields=UNIQUE_FIELDS, # 必须传列表!
22
23
  port=PORT,
23
- keep_strategy="min_id"
24
+ keep_strategy="max_id"
24
25
  )
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.1
2
2
  Name: cppackage
3
- Version: 0.2.9
3
+ Version: 0.3.1
4
4
  Summary: 超品集团自用的Python包
5
5
  Home-page: https://github.com/example/CPpackage
6
6
  Author: team-数智组
@@ -20,16 +20,6 @@ License-File: LICENSE
20
20
  Requires-Dist: pymysql
21
21
  Requires-Dist: pandas
22
22
  Requires-Dist: numpy
23
- Dynamic: author
24
- Dynamic: author-email
25
- Dynamic: classifier
26
- Dynamic: description
27
- Dynamic: description-content-type
28
- Dynamic: home-page
29
- Dynamic: license-file
30
- Dynamic: requires-dist
31
- Dynamic: requires-python
32
- Dynamic: summary
33
23
 
34
24
  # CPpackage
35
25
 
@@ -0,0 +1,13 @@
1
+ CPpackage/__init__.py,sha256=KpVaXkIzkNDl-dfSX8Rr7z9XFlipxx1nZ_GzS4Qls4I,173
2
+ CPpackage/core/__init__.py,sha256=92mF0310uQ5ujlgd-LCMs5kZVzfGRdcl67GHIRWhHcA,504
3
+ CPpackage/db/__init__.py,sha256=WhrLqsjq97KKHF7YV-HcZf9pRtHuqKhRjXDNPCBVbjY,107
4
+ CPpackage/db/config.py,sha256=A9HFCXqlrvssHLD1Ys9HpjDckavalFj31X1Np_aDNp4,729
5
+ CPpackage/db/sql_model.py,sha256=QnWEBb-ZqioZf62q-RQPgG8uJqLY9KgcyGW3zFkH4YY,10198
6
+ CPpackage/db/test.py,sha256=dEeoV5FBuWEt5MFujrt3fd2KSQ690zyw6mANgeiVRCg,1015
7
+ CPpackage/utils/__init__.py,sha256=sAespT0aoLr3O0WF27DwHLYF60VZgPA1tiT0JJ8s8zI,264
8
+ cppackage-0.3.1.dist-info/LICENSE,sha256=6Pj597LnvlRtq3Vgjkfp6zgBeBh7wl8jKE-nCFg4vZI,1065
9
+ cppackage-0.3.1.dist-info/METADATA,sha256=UZsPKX3T4zA7FbzYpb6Ppy0UvjzFjgq5zXMmZmFjqnE,2287
10
+ cppackage-0.3.1.dist-info/WHEEL,sha256=hPN0AlP2dZM_3ZJZWP4WooepkmU9wzjGgCLCeFjkHLA,92
11
+ cppackage-0.3.1.dist-info/entry_points.txt,sha256=SAzF2klkNyeNCqXuiNkDirN999l7v8CGCrHR0StD_oo,50
12
+ cppackage-0.3.1.dist-info/top_level.txt,sha256=FQrfWDbJistWQIrHW_Aoxoy_UWSzjOByWVcVS5ig9Tk,10
13
+ cppackage-0.3.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.10.2)
2
+ Generator: bdist_wheel (0.46.3)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,13 +0,0 @@
1
- CPpackage/__init__.py,sha256=KpVaXkIzkNDl-dfSX8Rr7z9XFlipxx1nZ_GzS4Qls4I,173
2
- CPpackage/core/__init__.py,sha256=92mF0310uQ5ujlgd-LCMs5kZVzfGRdcl67GHIRWhHcA,504
3
- CPpackage/db/__init__.py,sha256=WhrLqsjq97KKHF7YV-HcZf9pRtHuqKhRjXDNPCBVbjY,107
4
- CPpackage/db/config.py,sha256=A9HFCXqlrvssHLD1Ys9HpjDckavalFj31X1Np_aDNp4,729
5
- CPpackage/db/sql_model.py,sha256=tF31cF1SADulPGQ0TWcqhKOE393hdL4TMe6Xycv44UA,9942
6
- CPpackage/db/test.py,sha256=XzPTllM5S4s7M4NHJ_i4h_ZEEalnDTWhGd7d__nUS10,1011
7
- CPpackage/utils/__init__.py,sha256=sAespT0aoLr3O0WF27DwHLYF60VZgPA1tiT0JJ8s8zI,264
8
- cppackage-0.2.9.dist-info/licenses/LICENSE,sha256=6Pj597LnvlRtq3Vgjkfp6zgBeBh7wl8jKE-nCFg4vZI,1065
9
- cppackage-0.2.9.dist-info/METADATA,sha256=TaYeSok8htlPG0vIGSHkffQemPNolIT_koOk5B3mqpw,2516
10
- cppackage-0.2.9.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
11
- cppackage-0.2.9.dist-info/entry_points.txt,sha256=SAzF2klkNyeNCqXuiNkDirN999l7v8CGCrHR0StD_oo,50
12
- cppackage-0.2.9.dist-info/top_level.txt,sha256=FQrfWDbJistWQIrHW_Aoxoy_UWSzjOByWVcVS5ig9Tk,10
13
- cppackage-0.2.9.dist-info/RECORD,,