upplib 2.9.9__py3-none-any.whl → 3.2.2__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.
- upplib/__init__.py +2 -0
- upplib/clean_up_msg.py +36 -12
- upplib/db.py +0 -4
- upplib/file.py +88 -48
- upplib/file_text.py +980 -0
- upplib/format_data.py +198 -0
- upplib/index.py +16 -973
- upplib/query_log.py +51 -7
- upplib/redis_tool.py +1 -1
- upplib/util.py +2 -0
- {upplib-2.9.9.dist-info → upplib-3.2.2.dist-info}/METADATA +1 -1
- upplib-3.2.2.dist-info/RECORD +23 -0
- {upplib-2.9.9.dist-info → upplib-3.2.2.dist-info}/WHEEL +1 -1
- upplib-2.9.9.dist-info/RECORD +0 -21
- {upplib-2.9.9.dist-info → upplib-3.2.2.dist-info}/licenses/LICENSE +0 -0
- {upplib-2.9.9.dist-info → upplib-3.2.2.dist-info}/top_level.txt +0 -0
upplib/format_data.py
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
from upplib.index import *
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# 使用 sqlparse 库格式化 SQL 代码
|
|
5
|
+
def format_json(data_code=None):
|
|
6
|
+
if data_code is None:
|
|
7
|
+
return None
|
|
8
|
+
# 去除字符串首尾的多余空白字符
|
|
9
|
+
data_code = data_code.strip()
|
|
10
|
+
if len(data_code) == 0:
|
|
11
|
+
return None
|
|
12
|
+
# 去除 开头结尾非 json 的部分
|
|
13
|
+
while not data_code.startswith('{') and not data_code.startswith('[') and len(data_code):
|
|
14
|
+
data_code = data_code[1:]
|
|
15
|
+
data_code = data_code.strip()
|
|
16
|
+
while not data_code.endswith('}') and not data_code.endswith(']') and len(data_code):
|
|
17
|
+
data_code = data_code[:-1]
|
|
18
|
+
data_code = data_code.strip()
|
|
19
|
+
try:
|
|
20
|
+
# 尝试解析 json
|
|
21
|
+
parsed_json = json.loads(data_code)
|
|
22
|
+
except json.JSONDecodeError as e:
|
|
23
|
+
try:
|
|
24
|
+
# 尝试将 ' 替换成 "
|
|
25
|
+
# 尝试将 True 替换成 true
|
|
26
|
+
# 尝试将 False 替换成 false
|
|
27
|
+
data_code = re.sub(r"'", r'"', data_code).replace('True', 'true').replace('False', 'false').strip()
|
|
28
|
+
parsed_json = json.loads(data_code)
|
|
29
|
+
except json.JSONDecodeError as e:
|
|
30
|
+
try:
|
|
31
|
+
# 尝试将 \" 替换成 "
|
|
32
|
+
data_code = data_code.replace(r'\"', '"').strip()
|
|
33
|
+
parsed_json = json.loads(data_code)
|
|
34
|
+
except json.JSONDecodeError as e:
|
|
35
|
+
try:
|
|
36
|
+
# 尝试将 \' 替换成 "
|
|
37
|
+
data_code = data_code.replace(r"\'", '"').strip()
|
|
38
|
+
parsed_json = json.loads(data_code)
|
|
39
|
+
except json.JSONDecodeError as e:
|
|
40
|
+
return None
|
|
41
|
+
if parsed_json is None:
|
|
42
|
+
return None
|
|
43
|
+
# 缩进格式化
|
|
44
|
+
pretty_result = json.dumps(parsed_json, indent=4, ensure_ascii=False)
|
|
45
|
+
# 判断格式化后的 JSON 是否等价于原始 JSON(忽略空格)
|
|
46
|
+
if pretty_result.strip() == data_code.strip():
|
|
47
|
+
# 原始就是格式化的,返回紧凑格式
|
|
48
|
+
result = json.dumps(parsed_json, separators=(',', ':'), ensure_ascii=False)
|
|
49
|
+
else:
|
|
50
|
+
result = pretty_result
|
|
51
|
+
return result
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def format_sql(data_code=None):
|
|
55
|
+
if not data_code: return None
|
|
56
|
+
return sqlparse.format(data_code, reindent=True, keyword_case='upper')
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def extract_all_sql(log_content):
|
|
60
|
+
preparing_pattern = re.compile(r"Preparing:\s*(.*)")
|
|
61
|
+
parameters_pattern = re.compile(r"Parameters:\s*(.*)")
|
|
62
|
+
total_pattern = re.compile(r"Total:\s*(\d+)")
|
|
63
|
+
columns_pattern = re.compile(r"Columns:\s*(.*)")
|
|
64
|
+
row_pattern = re.compile(r"Row:\s*(.*)")
|
|
65
|
+
|
|
66
|
+
lines = log_content.splitlines()
|
|
67
|
+
all_results = []
|
|
68
|
+
|
|
69
|
+
current_sql, current_params, current_total = None, None, None
|
|
70
|
+
current_columns, current_rows_output = [], []
|
|
71
|
+
|
|
72
|
+
def build_output():
|
|
73
|
+
if not current_sql and not current_rows_output: return None
|
|
74
|
+
res_parts = []
|
|
75
|
+
insert_param_mappings = []
|
|
76
|
+
|
|
77
|
+
# 1. 处理 SQL 还原
|
|
78
|
+
if current_sql:
|
|
79
|
+
final_sql = current_sql
|
|
80
|
+
is_insert = current_sql.strip().upper().startswith("INSERT")
|
|
81
|
+
|
|
82
|
+
# 如果是 INSERT,提取字段名用于展示
|
|
83
|
+
col_names = []
|
|
84
|
+
if is_insert:
|
|
85
|
+
match = re.search(r"INSERT\s+INTO\s+\w+\s*\((.*?)\)", current_sql, re.IGNORECASE)
|
|
86
|
+
if match: col_names = [c.strip() for c in match.group(1).split(",")]
|
|
87
|
+
|
|
88
|
+
if current_params:
|
|
89
|
+
# 强大的参数切分逻辑(处理 JSON 中的逗号)
|
|
90
|
+
params_items = []
|
|
91
|
+
temp_item, bracket_stack = "", 0
|
|
92
|
+
for char in current_params:
|
|
93
|
+
if char in '([{':
|
|
94
|
+
bracket_stack += 1
|
|
95
|
+
elif char in ')]}':
|
|
96
|
+
bracket_stack -= 1
|
|
97
|
+
if char == ',' and bracket_stack == 0:
|
|
98
|
+
params_items.append(temp_item.strip());
|
|
99
|
+
temp_item = ""
|
|
100
|
+
else:
|
|
101
|
+
temp_item += char
|
|
102
|
+
if temp_item: params_items.append(temp_item.strip())
|
|
103
|
+
|
|
104
|
+
for idx, item in enumerate(params_items):
|
|
105
|
+
type_match = re.search(r'\(\w+\)$', item)
|
|
106
|
+
val = item[:type_match.start()].strip() if type_match else item.strip()
|
|
107
|
+
|
|
108
|
+
# 值格式化
|
|
109
|
+
if val.lower() == "null":
|
|
110
|
+
replacement = "NULL"
|
|
111
|
+
elif val.lower() in ["true", "false"]:
|
|
112
|
+
replacement = f"'{val.lower()}'"
|
|
113
|
+
elif re.match(r'^-?\d+(\.\d+)?$', val):
|
|
114
|
+
replacement = val
|
|
115
|
+
else:
|
|
116
|
+
replacement = f"'{val.replace("'", "''")}'"
|
|
117
|
+
|
|
118
|
+
final_sql = final_sql.replace("?", replacement, 1)
|
|
119
|
+
|
|
120
|
+
# 仅 INSERT 记录映射关系
|
|
121
|
+
if is_insert and idx < len(col_names):
|
|
122
|
+
insert_param_mappings.append(f"{col_names[idx]} = {replacement}")
|
|
123
|
+
|
|
124
|
+
res_parts.append(format_sql(final_sql))
|
|
125
|
+
|
|
126
|
+
# 只有 INSERT 输出这个详细列表
|
|
127
|
+
if is_insert and insert_param_mappings:
|
|
128
|
+
res_parts.append("============INSERT_DATA_start============")
|
|
129
|
+
res_parts.extend(insert_param_mappings)
|
|
130
|
+
res_parts.append("============INSERT_DATA___end============")
|
|
131
|
+
|
|
132
|
+
# 2. 处理 SELECT 结果数据 (Result Data)
|
|
133
|
+
if current_rows_output:
|
|
134
|
+
res_parts.append("============SELECT_DATA_start============")
|
|
135
|
+
for i, row in enumerate(current_rows_output):
|
|
136
|
+
if len(current_rows_output) > 1:
|
|
137
|
+
res_parts.append(f"Row {i + 1}:")
|
|
138
|
+
res_parts.extend([f"{kv}" for kv in row])
|
|
139
|
+
if i < len(current_rows_output) - 1:
|
|
140
|
+
res_parts.append("----------------------------------------")
|
|
141
|
+
res_parts.append("============SELECT_DATA___end============")
|
|
142
|
+
|
|
143
|
+
if current_total is not None:
|
|
144
|
+
res_parts.append(f"Total: {current_total}")
|
|
145
|
+
|
|
146
|
+
return "\n".join(res_parts)
|
|
147
|
+
|
|
148
|
+
for line in lines:
|
|
149
|
+
if "Preparing:" in line:
|
|
150
|
+
if current_sql or current_rows_output: all_results.append(build_output())
|
|
151
|
+
m = preparing_pattern.search(line)
|
|
152
|
+
current_sql = m.group(1).strip() if m else None
|
|
153
|
+
current_params, current_total, current_columns, current_rows_output = None, None, [], []
|
|
154
|
+
elif "Parameters:" in line:
|
|
155
|
+
m = parameters_pattern.search(line)
|
|
156
|
+
if m: current_params = m.group(1).strip()
|
|
157
|
+
elif "Columns:" in line:
|
|
158
|
+
m = columns_pattern.search(line)
|
|
159
|
+
if m: current_columns = [c.strip() for c in m.group(1).split(",")]
|
|
160
|
+
elif "Row:" in line and current_columns:
|
|
161
|
+
m = row_pattern.search(line)
|
|
162
|
+
if m:
|
|
163
|
+
vals = [v.strip() for v in m.group(1).split(",")]
|
|
164
|
+
row_kv = [f"{c} = {v}" for c, v in zip(current_columns, vals)]
|
|
165
|
+
current_rows_output.append(row_kv)
|
|
166
|
+
elif "Total:" in line:
|
|
167
|
+
m = total_pattern.search(line)
|
|
168
|
+
if m: current_total = m.group(1).strip()
|
|
169
|
+
|
|
170
|
+
if current_sql or current_rows_output: all_results.append(build_output())
|
|
171
|
+
all_results = "\n\n".join(filter(None, all_results))
|
|
172
|
+
if not all_results:
|
|
173
|
+
return None
|
|
174
|
+
return all_results
|
|
175
|
+
|
|
176
|
+
# # 测试输出
|
|
177
|
+
# log = '''
|
|
178
|
+
# ==> Preparing: INSERT INTO credit_apply_letter ( user_id, requester, credit_apply_no, seq_id, apply_time, status, app_line, deleted ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )
|
|
179
|
+
# ==> Parameters: 1162123669614335312(Long), trade(String), 1162873570904262396(String), 1156947856065503112(String), 2026-01-20T19:00:37.046(LocalDateTime), NO_CREDIT(String), (String), false(Boolean)
|
|
180
|
+
# <== Updates: 1
|
|
181
|
+
# ==> Preparing: UPDATE delay_task SET strategy_name = ?, request_data = ?, status = ?, task_type = ?, rpc_context = ?, biz_type = ?, execute_cnt = ?, create_time = ?, modify_time = ?, biz_flow_number = ?, seq_id = ?, request_id = ?, decision_id = ? WHERE id = ?
|
|
182
|
+
# ==> Parameters: apply(String), {"strategyName":"apply","user_id":1162123669614335312,"gaid":"2cc1b43f-5862-416a-bf1b-75b4167cdcf6","credit_apply_no":"1162873570904262396","customer_id":1162123669614336225,"decisionStage":"apply"}(String), processing(String), SYSTEM(String), {"requester":"trade","seq_id":"1156947856065503112","biz_type":"APPLY","report_id":"90986cb0fae94e75b177181f022cfdd9","user_channel":"Null_GP","header":{"tpCode":"rcs-provider","requestId":"1156947856065503112","scene":"APPLY"},"input_data":{"engineCode":"jcl_20240927000001","organId":"11","fields":{"biz_flow_number":"1162873570904262396","user_channel":"Null_GP","user_id":1162123669614335312,"gaid":"2cc1b43f-5862-416a-bf1b-75b4167cdcf6","biz_type":"APPLY","seq_id":"1156947856065503112","credit_apply_no":"1162873570904262396","customer_id":1162123669614336225,"loan_apply_no":"-1"}}}(String), APPLY(String), 1(Integer), 2026-01-20T19:00:37(LocalDateTime), 2026-01-20T19:00:37.069(LocalDateTime), 1162873570904262396(String), 1156947856065503112(String), 1156947856065503112(String), 20260120190037058APPLY03566(String), 1117889(Long)
|
|
183
|
+
# ==> Preparing: SELECT * FROM rcs_strategy_report WHERE seq_id = ?
|
|
184
|
+
# ==> Parameters: 1156947856065503112(String)
|
|
185
|
+
# <== Columns: id, seq_id, requester, strategy_name, biz_type, status, header, input_data, mid_result, result, is_deleted, duration, created_time, updated_time, version, user_id
|
|
186
|
+
# <== Row: 6495974, 1156947856065503112, trade, apply, APPLY, PROCESSING, <<BLOB>>, <<BLOB>>, <<BLOB>>, <<BLOB>>, N, null, 2026-01-20 19:00:37, 2026-01-20 19:00:37, 1, 1162123669614335312
|
|
187
|
+
# <== Row: 6495974, 1156947856065503112, trade, apply, APPLY, PROCESSING, <<BLOB>>, <<BLOB>>, <<BLOB>>, <<BLOB>>, N, null, 2026-01-20 19:00:37, 2026-01-20 19:00:37, 1, 1162123669614335312
|
|
188
|
+
# <== Total: 2
|
|
189
|
+
#
|
|
190
|
+
# '''
|
|
191
|
+
# log = '''
|
|
192
|
+
#
|
|
193
|
+
# {"strategyName":"apply","user_id":980365936454085953,"gaid":"b37e2bf1-2579-48ad-8058-4299f392e192","credit_apply_no":"1162873570904261771","customer_id":1162137121451927630,"decisionStage":"apply"}
|
|
194
|
+
#
|
|
195
|
+
#
|
|
196
|
+
# '''
|
|
197
|
+
# b = extract_all_sql('select * from review.audit_user order by id desc limit 10;')
|
|
198
|
+
# print(b)
|