database-smartools 0.0.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.
@@ -0,0 +1,396 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ @项目名称 : python-main
4
+ @文件名称 : mysql_extend.py
5
+ @创建人 : zhongbinjie
6
+ @创建时间 : 2025/6/7 19:06
7
+ @文件说明 :
8
+ @企业名称 : 深圳市赢和信息技术有限公司
9
+ @Copyright:2025-2035, 深圳市赢和信息技术有限公司. All rights Reserved.
10
+ """
11
+
12
+ from sqlalchemy import create_engine
13
+ import cx_Oracle
14
+ from utils import config, logger, texter
15
+ import numpy as np
16
+
17
+ # 获取数据池
18
+ cx_Oracle.init_oracle_client(lib_dir=config.MAP['db_lib']) # 替换为你的Instant Client路径
19
+ POOL_MAP = {}
20
+
21
+
22
+ def get_pool():
23
+ pool = cx_Oracle.SessionPool(user=config.MAP['db_user'],
24
+ password=config.MAP['db_password'],
25
+ dsn=cx_Oracle.makedsn(config.MAP['db_host'], config.MAP['db_port'],
26
+ config.MAP['db_name']),
27
+ min=2, max=15, increment=1, threaded=False)
28
+ return pool
29
+
30
+
31
+ def get_pool_by_key(db_key, refresh=False):
32
+ global POOL_MAP
33
+ scan_db_conf = f"""
34
+ SELECT user_name,pass_word,url FROM task_template_data_source WHERE db_key = :db_key
35
+ """
36
+ params = {"db_key": db_key}
37
+ pool = get_pool()
38
+ conn, message = get_conn(pool)
39
+ select_result, select_message = select(conn, scan_db_conf, params)
40
+ if not select_result:
41
+ return None, select_message
42
+ db_conf = select_result['data'][0]
43
+ user_name = db_conf['user_name']
44
+ pass_word = db_conf['pass_word']
45
+ url = db_conf['url']
46
+
47
+ url_map = texter.parse_jdbc_url(url)
48
+ pool = None
49
+ if db_key not in POOL_MAP.keys() or refresh:
50
+ if url_map['type'] == 'oracle':
51
+ try:
52
+ pool = cx_Oracle.SessionPool(user=user_name,
53
+ password=pass_word,
54
+ dsn=cx_Oracle.makedsn(url_map['host'], url_map['port'],
55
+ url_map['database']),
56
+ min=2, max=15, increment=1, threaded=False)
57
+ except Exception as e:
58
+ message = f"实例化数据库连接池失败,错误信息:{e}"
59
+ logger.error(message)
60
+
61
+ return None, message
62
+
63
+ POOL_MAP[db_key] = {
64
+ "pool": pool,
65
+ "db_type": url_map['type']
66
+ }
67
+ logger.debug(f"创建新的连接池,db_key: {db_key}")
68
+ else:
69
+ pool = POOL_MAP[db_key][0]
70
+ logger.debug(f"使用已有连接池,db_key: {db_key}")
71
+ return pool, ""
72
+
73
+
74
+ def close_pool(pool):
75
+ pool.close()
76
+ logger.debug(f"关闭连接池")
77
+
78
+
79
+ def get_conn(pool):
80
+ message = ""
81
+ try:
82
+ conn = pool.acquire()
83
+ logger.debug(f"从连接池中获取数据库连接")
84
+ return conn, message
85
+ except Exception as e:
86
+ message = f'获取数据连接异常,错误信息:{e}'
87
+ logger.error(f'获取数据连接异常,错误信息:{e}')
88
+ return None, message
89
+
90
+
91
+ def get_conn_map(pool_map):
92
+ message = ""
93
+ try:
94
+ conn = pool_map['pool'].acquire()
95
+ db_type = pool_map['db_type']
96
+ conn_map = {
97
+ "conn": conn,
98
+ "db_type": db_type
99
+ }
100
+ logger.debug(f"从连接池中获取数据库连接和数据库类型")
101
+ return conn_map, message
102
+ except Exception as e:
103
+ message = f'获取数据连接异常,错误信息:{e}'
104
+ logger.error(f'获取数据连接异常,错误信息:{e}')
105
+ return None, message
106
+
107
+
108
+ def get_engine():
109
+ url = f'oracle+cx_oracle://{config.DB_USER}:{config.DB_PASSWORD}@{config.DB_HOST}:{config.DB_PORT}/?service_name={config.DB_NAME}'
110
+ engine = create_engine(url,
111
+ pool_size=30,
112
+ max_overflow=20,
113
+ pool_timeout=30,
114
+ pool_recycle=1800,
115
+ pool_pre_ping=True)
116
+
117
+ return engine
118
+
119
+
120
+ def close_engine(engine):
121
+ engine.dispose()
122
+
123
+
124
+ def close_conn(pool, conn):
125
+ if isinstance(pool, dict):
126
+ pool = pool['pool']
127
+
128
+ if isinstance(conn, dict):
129
+ conn = conn['conn']
130
+ pool.release(conn)
131
+ logger.debug(f"从连接池中释放数据库连接")
132
+ return conn
133
+
134
+
135
+ def commit(conn):
136
+ if isinstance(conn, dict):
137
+ conn = conn['conn']
138
+ conn.commit()
139
+ logger.debug(f"数据库连接-提交事务")
140
+ return
141
+
142
+
143
+ def rollback(conn):
144
+ if isinstance(conn, dict):
145
+ conn = conn['conn']
146
+ conn.rollback()
147
+ logger.debug(f"数据库连接-回滚事务")
148
+ return
149
+
150
+
151
+ def select(conn, sql, params=None):
152
+ result = None
153
+ message = ""
154
+ with conn.cursor() as cursor:
155
+ try:
156
+ if params:
157
+ rs = cursor.execute(sql, params).fetchall()
158
+ result = {
159
+ 'data': rs,
160
+ 'desc': cursor.description
161
+ }
162
+ else:
163
+ rs = cursor.execute(sql).fetchall()
164
+ result = {
165
+ 'data': rs,
166
+ 'desc': cursor.description
167
+ }
168
+
169
+ logger.debug(f"[数据查询]sql: {sql}, 参数列表: {params}")
170
+
171
+ except Exception as e:
172
+ message = f"[数据查询]异常:{e}"
173
+ logger.error(message)
174
+ return None, message
175
+
176
+ # print(result)
177
+ data = []
178
+ for row in result['data']:
179
+ item_map = {}
180
+ for index, item in enumerate(row):
181
+ if result['desc'][index][1] == cx_Oracle.DATETIME and item is not None:
182
+ item = item.strftime("%Y-%m-%d %H:%M:%S")
183
+
184
+ item_map[result['desc'][index][0].lower()] = item
185
+ data.append(item_map)
186
+ result['data'] = data
187
+ return result, message
188
+
189
+
190
+ def select_by_map(conn_map, sql, params=None):
191
+ result = None
192
+ message = ""
193
+ conn = conn_map['conn']
194
+ with conn.cursor() as cursor:
195
+ try:
196
+ if params:
197
+ rs = cursor.execute(sql, params).fetchall()
198
+ result = {
199
+ 'data': rs,
200
+ 'desc': cursor.description
201
+ }
202
+ else:
203
+ rs = cursor.execute(sql).fetchall()
204
+ result = {
205
+ 'data': rs,
206
+ 'desc': cursor.description
207
+ }
208
+
209
+ logger.debug(f"[数据查询]sql: {sql}, 参数列表: {params}")
210
+
211
+ column_types = []
212
+ for desc in result['desc']:
213
+ column_types.append(desc[1])
214
+ result['data_types'] = column_types
215
+
216
+ except Exception as e:
217
+ message = f"[数据查询]异常:{e}"
218
+ logger.error(message)
219
+ return None, message
220
+
221
+ # print(result)
222
+ data = []
223
+ for row in result['data']:
224
+ item_map = {}
225
+ for index, item in enumerate(row):
226
+ # if result['desc'][index][1] == cx_Oracle.DATETIME and item is not None:
227
+ # item = item.strftime("%Y-%m-%d")
228
+
229
+ if result['desc'][index][1] == cx_Oracle.TIMESTAMP and item is not None:
230
+ item = item.strftime("%Y-%m-%d %H:%M:%S")
231
+
232
+ item_map[result['desc'][index][0].lower()] = item
233
+
234
+ data.append(item_map)
235
+ result['data'] = data
236
+ return result, message
237
+
238
+
239
+ def delete(conn, sql, params=None):
240
+ message = ""
241
+ with conn.cursor() as cursor:
242
+ try:
243
+ if params:
244
+ cursor.execute(sql, params)
245
+ else:
246
+ cursor.execute(sql)
247
+
248
+ logger.debug(f"[数据删除]sql: {sql}, 参数列表: {params}")
249
+ except Exception as e:
250
+ message = f"[数据删除]异常:{e}"
251
+ logger.error(message)
252
+ return False, message
253
+
254
+ return True, message
255
+
256
+
257
+ def delete_by_map(conn_map, sql, params=None):
258
+ message = ""
259
+ conn = conn_map['conn']
260
+ with conn.cursor() as cursor:
261
+ try:
262
+ if params:
263
+ cursor.execute(sql, params)
264
+ else:
265
+ cursor.execute(sql)
266
+
267
+ logger.debug(f"[数据删除]sql: {sql}, 参数列表: {params}")
268
+ except Exception as e:
269
+ message = f"[数据删除]异常:{e}"
270
+ logger.error(message)
271
+ return False, message
272
+
273
+ return True, message
274
+
275
+
276
+ def update(conn, sql, params=None):
277
+ message = ""
278
+ with conn.cursor() as cursor:
279
+ try:
280
+ if params:
281
+ cursor.execute(sql, params)
282
+ else:
283
+ cursor.execute(sql)
284
+
285
+ logger.debug(f"[数据更新]sql: {sql}, 参数列表: {params}")
286
+ except Exception as e:
287
+ message = f"[数据更新]异常:{e}"
288
+ logger.error(message)
289
+ return False, message
290
+ return True, message
291
+
292
+
293
+ def update_by_map(conn_map, sql, params=None):
294
+ message = ""
295
+ conn = conn_map['conn']
296
+ with conn.cursor() as cursor:
297
+ try:
298
+ if params:
299
+ cursor.execute(sql, params)
300
+ else:
301
+ cursor.execute(sql)
302
+
303
+ logger.debug(f"[数据更新]sql: {sql}, 参数列表: {params}")
304
+ except Exception as e:
305
+ message = f"[数据更新]异常:{e}"
306
+ logger.info(message)
307
+ return False, message
308
+ return True, message
309
+
310
+
311
+ def insert(conn, sql, params=None):
312
+ message = ""
313
+ with conn.cursor() as cursor:
314
+ try:
315
+ if params:
316
+ cursor.execute(sql, params)
317
+ else:
318
+ cursor.execute(sql)
319
+
320
+ logger.debug(f"[数据库新增]sql: {sql}, 参数列表: {params}")
321
+
322
+ except Exception as e:
323
+ message = f"[数据库新增]异常:{e}"
324
+ logger.error(message)
325
+ return False, message
326
+
327
+ return True, message
328
+
329
+
330
+ def insert_by_map(conn_map, sql, params=None):
331
+ message = ""
332
+ conn = conn_map['conn']
333
+ with conn.cursor() as cursor:
334
+ try:
335
+ if params:
336
+ cursor.execute(sql, params)
337
+ else:
338
+ cursor.execute(sql)
339
+
340
+ logger.debug(f"[数据库新增]sql: {sql}, 参数列表: {params}")
341
+
342
+ except Exception as e:
343
+ message = f"[数据库新增]异常:{e}"
344
+ logger.error(message)
345
+ return False, message
346
+
347
+ return True, message
348
+
349
+
350
+ def insert_by_dataframe(conn_map, df, table_name):
351
+ message = ""
352
+ conn = conn_map
353
+ if isinstance(conn_map, dict):
354
+ conn = conn_map['conn']
355
+
356
+ columns = df.columns.tolist() # 获得dataframe的列名
357
+ data_to_insert = [tuple(row) for row in df.to_numpy()] # dataframe转换numpy
358
+ print(data_to_insert)
359
+ with conn.cursor() as cursor:
360
+ try:
361
+ sql = df_insert2db(columns, save_table_name=table_name)
362
+ logger.debug(f"[数据库新增][dataframe]sql: {sql}")
363
+ batch_size = int(config.MAP['batch_size'])
364
+ for i in range(0, len(data_to_insert), batch_size):
365
+ batch_data = data_to_insert[i: i + batch_size]
366
+ print(batch_data)
367
+ logger.debug(f"[分批写入][dataframe]当前载入至第{min(i + batch_size, len(data_to_insert))}行。")
368
+ cursor.executemany(sql, batch_data)
369
+ conn.commit() # 批量执行query_sql, 每批次提交一次
370
+
371
+ except Exception as e:
372
+ message = f"[数据库新增][dataframe]异常:{e}"
373
+ logger.error(message)
374
+ conn.rollback()
375
+ return False, message
376
+
377
+ return True, message
378
+
379
+
380
+ def df_insert2db(columns, save_table_name):
381
+ """
382
+ Args:
383
+ columns: 以列表的形式
384
+ save_table_name: 保存table的名字
385
+ Returns:直接的insert到Oracle的sql语句,字符串格式
386
+ """
387
+ s = ''
388
+ for i in range(len(columns)):
389
+ s = s + columns[i] + '-'
390
+ sql_columns = s.replace('-', ',')[:-1] # 不要最后输出的逗号
391
+ sql_number_str = ''
392
+ for i in range(1, len(columns) + 1, 1):
393
+ sql_number_str = sql_number_str + ':' + str(i) + ',' # ':1,:2,:3,:4,:5,:6'
394
+ sql_number_str = sql_number_str[:-1]
395
+ query_sql = 'insert into ' + save_table_name + '(' + sql_columns + ') values(' + sql_number_str + ') '
396
+ return query_sql
@@ -0,0 +1,55 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ @项目名称 : yhfin-data-agent
4
+ @文件名称 : oceanbase_extend.py
5
+ @创建人 : zhongbinjie
6
+ @创建时间 : 2025/8/14 18:42
7
+ @文件说明 :
8
+ @企业名称 : 深圳市赢和信息技术有限公司
9
+ @Copyright:2025-2035, 深圳市赢和信息技术有限公司. All rights Reserved.
10
+ """
11
+ import jaydebeapi
12
+
13
+ def formatter(result):
14
+ data = []
15
+ if not result or not result['data']:
16
+ return data
17
+ for index, row in enumerate(result['data']):
18
+ item_map = {}
19
+ for index, item in enumerate(row):
20
+ #
21
+ # if result['desc'][index][1] == jaydebeapi.DATETIME and item is not None:
22
+ # item = texter.convert_to_oracle_datetime(item, 'TIMESTAMP')
23
+ #
24
+ # if result['desc'][index][1] == jaydebeapi.DATE and item is not None:
25
+ # item = texter.convert_to_oracle_datetime(item, 'DATE')
26
+
27
+ # if result['desc'][index][1] not in ['VARCHAR2', 'DATE']:
28
+ # print(result['desc'][index][1])
29
+ item_map[result['desc'][index][0].lower()] = item
30
+ data.append(item_map)
31
+
32
+ return data
33
+
34
+ def test_connect_oceanbase(url, user, password, driver, jarFile):
35
+ """
36
+ 测试连接 OceanBase 数据库
37
+ :param url: 数据库连接字符串
38
+ :param user: 用户名
39
+ :param password: 密码
40
+ :param driver: 驱动类名
41
+ :param jarFile: 驱动 JAR 文件路径
42
+ :return:
43
+ """
44
+ sqlStr = """select 1 from dual"""
45
+ conn = jaydebeapi.connect(driver, url, [user, password], jarFile)
46
+ return conn
47
+
48
+
49
+ def test():
50
+ print()
51
+
52
+
53
+ if __name__ == '__main__':
54
+ # sqlStr = "SELECT * FROM user_tab_columns WHERE table_name = 'T_CHECK_LOG_TEST'"
55
+ None
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ @项目名称 : python-main
4
+ @文件名称 : oracle_extend.py
5
+ @创建人 : zhongbinjie
6
+ @创建时间 : 2025/6/7 19:06
7
+ @文件说明 :
8
+ @企业名称 : 深圳市赢和信息技术有限公司
9
+ @Copyright:2025-2035, 深圳市赢和信息技术有限公司. All rights Reserved.
10
+ """
11
+
12
+ import oracledb
13
+ def formatter(result):
14
+ data = []
15
+ for row in result['data']:
16
+ item_map = {}
17
+ for index, item in enumerate(row):
18
+ # if result['desc'][index][1] == cx_Oracle.DATETIME and item is not None:
19
+ # item = item.strftime("%Y-%m-%d")
20
+
21
+ if result['desc'][index][1] == oracledb.TIMESTAMP and item is not None:
22
+ item = item.strftime("%Y-%m-%d %H:%M:%S")
23
+
24
+ item_map[result['desc'][index][0].lower()] = item
25
+
26
+ data.append(item_map)
27
+ return data