wcp-library 1.2.9__py3-none-any.whl → 1.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.
@@ -1,261 +0,0 @@
1
- import logging
2
- from typing import Optional
3
-
4
- import numpy as np
5
- import pandas as pd
6
- import oracledb
7
- from oracledb import AsyncConnectionPool
8
-
9
- from wcp_library.async_sql import retry
10
-
11
- logger = logging.getLogger(__name__)
12
-
13
-
14
- async def _connect_warehouse(username: str, password: str, hostname: str, port: int, database: str, min_connections: int,
15
- max_connections: int) -> AsyncConnectionPool:
16
- """
17
- Create Warehouse Connection
18
-
19
- :param username: username
20
- :param password: password
21
- :param hostname: hostname
22
- :param port: port
23
- :param database: database
24
- :param min_connections:
25
- :param max_connections:
26
- :return: session_pool
27
- """
28
-
29
- dsn = oracledb.makedsn(hostname, port, sid=database)
30
- session_pool = oracledb.create_pool_async(
31
- user=username,
32
- password=password,
33
- dsn=dsn,
34
- min=min_connections,
35
- max=max_connections,
36
- increment=1
37
- )
38
- return session_pool
39
-
40
-
41
- class AsyncOracleConnection(object):
42
- """
43
- SQL Connection Class
44
-
45
- :return: None
46
- """
47
-
48
- def __init__(self, min_connections: int = 2, max_connections: int = 5):
49
- self._db_service: str = "Oracle"
50
- self._username: Optional[str] = None
51
- self._password: Optional[str] = None
52
- self._hostname: Optional[str] = None
53
- self._port: Optional[int] = None
54
- self._database: Optional[str] = None
55
- self._sid: Optional[str] = None
56
- self._session_pool: Optional[AsyncConnectionPool] = None
57
-
58
- self.min_connections = min_connections
59
- self.max_connections = max_connections
60
-
61
- self._retry_count = 0
62
- self.retry_limit = 50
63
- self.retry_error_codes = ['ORA-01033', 'DPY-6005', 'DPY-4011']
64
-
65
- @retry
66
- async def _connect(self) -> None:
67
- """
68
- Connect to the warehouse
69
-
70
- :return: None
71
- """
72
-
73
- sid_or_service = self._database if self._database else self._sid
74
-
75
- self._session_pool = await _connect_warehouse(self._username, self._password, self._hostname, self._port,
76
- sid_or_service, self.min_connections, self.max_connections)
77
-
78
- async def set_user(self, credentials_dict: dict) -> None:
79
- """
80
- Set the user credentials and connect
81
-
82
- :param credentials_dict: dictionary of connection details
83
- :return: None
84
- """
85
-
86
- if not ([credentials_dict['Service'] or credentials_dict['SID']]):
87
- raise ValueError("Either Service or SID must be provided")
88
-
89
- self._username: Optional[str] = credentials_dict['UserName']
90
- self._password: Optional[str] = credentials_dict['Password']
91
- self._hostname: Optional[str] = credentials_dict['Host']
92
- self._port: Optional[int] = int(credentials_dict['Port'])
93
- self._database: Optional[str] = credentials_dict['Service'] if 'Service' in credentials_dict else None
94
- self._sid: Optional[str] = credentials_dict['SID'] if 'SID' in credentials_dict else None
95
-
96
- await self._connect()
97
-
98
- async def close_connection(self) -> None:
99
- """
100
- Close the connection
101
-
102
- :return: None
103
- """
104
-
105
- await self._session_pool.close()
106
-
107
- @retry
108
- async def execute(self, query: str) -> None:
109
- """
110
- Execute the query
111
-
112
- :param query: query
113
- :return: None
114
- """
115
-
116
- async with self._session_pool.acquire() as connection:
117
- with connection.cursor() as cursor:
118
- await cursor.execute(query)
119
- await connection.commit()
120
-
121
- @retry
122
- async def safe_execute(self, query: str, packed_values: dict) -> None:
123
- """
124
- Execute the query without SQL Injection possibility, to be used with external facing projects.
125
-
126
- :param query: query
127
- :param packed_values: dictionary of values
128
- :return: None
129
- """
130
-
131
- async with self._session_pool.acquire() as connection:
132
- with connection.cursor() as cursor:
133
- await cursor.execute(query, packed_values)
134
- await connection.commit()
135
-
136
- @retry
137
- async def execute_multiple(self, queries: list[list[str, dict]]) -> None:
138
- """
139
- Execute multiple queries
140
-
141
- :param queries: list of queries
142
- :return: None
143
- """
144
-
145
- async with self._session_pool.acquire() as connection:
146
- with connection.cursor() as cursor:
147
- for item in queries:
148
- query = item[0]
149
- packed_values = item[1]
150
- if packed_values:
151
- await cursor.execute(query, packed_values)
152
- else:
153
- await cursor.execute(query)
154
- await connection.commit()
155
-
156
- @retry
157
- async def execute_many(self, query: str, dictionary: list[dict]) -> None:
158
- """
159
- Execute many queries
160
-
161
- :param query: query
162
- :param dictionary: dictionary of values
163
- :return: None
164
- """
165
-
166
- async with self._session_pool.acquire() as connection:
167
- with connection.cursor() as cursor:
168
- await cursor.executemany(query, dictionary)
169
- await connection.commit()
170
-
171
- @retry
172
- async def fetch_data(self, query: str, packed_data=None):
173
- """
174
- Fetch the data from the query
175
-
176
- :param query: query
177
- :param packed_data: packed data
178
- :return: rows
179
- """
180
-
181
- async with self._session_pool.acquire() as connection:
182
- with connection.cursor() as cursor:
183
- if packed_data:
184
- await cursor.execute(query, packed_data)
185
- else:
186
- await cursor.execute(query)
187
- rows = await cursor.fetchall()
188
- return rows
189
-
190
- @retry
191
- async def remove_matching_data(self, dfObj: pd.DataFrame, outputTableName: str, match_cols: list) -> None:
192
- """
193
- Remove matching data from the warehouse
194
-
195
- :param dfObj: DataFrame
196
- :param outputTableName: output table name
197
- :param match_cols: list of columns
198
- :return: None
199
- """
200
-
201
- df = dfObj[match_cols]
202
- param_list = []
203
- for column in match_cols:
204
- param_list.append(f"{column} = :{column}")
205
- if len(param_list) > 1:
206
- params = ' AND '.join(param_list)
207
- else:
208
- params = param_list[0]
209
-
210
- main_dict = df.to_dict('records')
211
- query = f"""DELETE FROM {outputTableName} WHERE {params}"""
212
- await self.execute_many(query, main_dict)
213
-
214
- @retry
215
- async def export_DF_to_warehouse(self, dfObj: pd.DataFrame, outputTableName: str, columns: list, remove_nan=False) -> None:
216
- """
217
- Export the DataFrame to the warehouse
218
-
219
- :param dfObj: DataFrame
220
- :param outputTableName: output table name
221
- :param columns: list of columns
222
- :param remove_nan: remove NaN values
223
- :return: None
224
- """
225
-
226
- col = ', '.join(columns)
227
- bindList = []
228
- for column in columns:
229
- bindList.append(':' + column)
230
- bind = ', '.join(bindList)
231
-
232
- if remove_nan:
233
- dfObj = dfObj.replace({np.nan: None})
234
- main_dict = dfObj.to_dict('records')
235
-
236
- query = """INSERT INTO {} ({}) VALUES ({})""".format(outputTableName, col, bind)
237
- await self.execute_many(query, main_dict)
238
-
239
- @retry
240
- async def truncate_table(self, tableName: str) -> None:
241
- """
242
- Truncate the table
243
-
244
- :param tableName: table name
245
- :return: None
246
- """
247
-
248
- truncateQuery = """TRUNCATE TABLE {}""".format(tableName)
249
- await self.execute(truncateQuery)
250
-
251
- @retry
252
- async def empty_table(self, tableName: str) -> None:
253
- """
254
- Empty the table
255
-
256
- :param tableName: table name
257
- :return: None
258
- """
259
-
260
- deleteQuery = """DELETE FROM {}""".format(tableName)
261
- await self.execute(deleteQuery)
@@ -1,252 +0,0 @@
1
- import logging
2
- from typing import Optional
3
-
4
- import numpy as np
5
- import pandas as pd
6
- from psycopg.sql import SQL
7
- from psycopg_pool import AsyncConnectionPool
8
-
9
- from wcp_library.async_sql import retry
10
-
11
- logger = logging.getLogger(__name__)
12
-
13
-
14
- async def _connect_warehouse(username: str, password: str, hostname: str, port: int, database: str, min_connections: int,
15
- max_connections: int) -> AsyncConnectionPool:
16
- """
17
- Create Warehouse Connection
18
-
19
- :param username: username
20
- :param password: password
21
- :param hostname: hostname
22
- :param port: port
23
- :param database: database
24
- :param min_connections:
25
- :param max_connections:
26
- :return: session_pool
27
- """
28
-
29
- url = f"postgres://{username}:{password}@{hostname}:{port}/{database}"
30
-
31
- session_pool = AsyncConnectionPool(
32
- conninfo=url,
33
- min_size=min_connections,
34
- max_size=max_connections,
35
- )
36
- await session_pool.open()
37
- return session_pool
38
-
39
-
40
- class AsyncPostgresConnection(object):
41
- """
42
- SQL Connection Class
43
-
44
- :return: None
45
- """
46
-
47
- def __init__(self, min_connections: int = 2, max_connections: int = 5):
48
- self._username: Optional[str] = None
49
- self._password: Optional[str] = None
50
- self._hostname: Optional[str] = None
51
- self._port: Optional[int] = None
52
- self._database: Optional[str] = None
53
- self._session_pool: Optional[AsyncConnectionPool] = None
54
-
55
- self.min_connections = min_connections
56
- self.max_connections = max_connections
57
-
58
- self._retry_count = 0
59
- self.retry_limit = 50
60
- self.retry_error_codes = ['08001', '08004']
61
-
62
- @retry
63
- async def _connect(self) -> None:
64
- """
65
- Connect to the warehouse
66
-
67
- :return: None
68
- """
69
-
70
- self._session_pool = await _connect_warehouse(self._username, self._password, self._hostname, self._port,
71
- self._database, self.min_connections, self.max_connections)
72
-
73
- async def set_user(self, credentials_dict: dict) -> None:
74
- """
75
- Set the user credentials and connect
76
-
77
- :param credentials_dict: dictionary of connection details
78
- :return: None
79
- """
80
-
81
- self._username: Optional[str] = credentials_dict['UserName']
82
- self._password: Optional[str] = credentials_dict['Password']
83
- self._hostname: Optional[str] = credentials_dict['Host']
84
- self._port: Optional[int] = int(credentials_dict['Port'])
85
- self._database: Optional[str] = credentials_dict['Database']
86
-
87
- await self._connect()
88
-
89
- async def close_connection(self) -> None:
90
- """
91
- Close the connection
92
-
93
- :return: None
94
- """
95
-
96
- await self._session_pool.close()
97
-
98
- @retry
99
- async def execute(self, query: SQL | str) -> None:
100
- """
101
- Execute the query
102
-
103
- :param query: query
104
- :return: None
105
- """
106
-
107
- async with self._session_pool.connection() as connection:
108
- await connection.execute(query)
109
-
110
- @retry
111
- async def safe_execute(self, query: SQL | str, packed_values: dict) -> None:
112
- """
113
- Execute the query without SQL Injection possibility, to be used with external facing projects.
114
-
115
- :param query: query
116
- :param packed_values: dictionary of values
117
- :return: None
118
- """
119
-
120
- async with self._session_pool.connection() as connection:
121
- await connection.execute(query, packed_values)
122
-
123
- @retry
124
- async def execute_multiple(self, queries: list[list[SQL | str, dict]]) -> None:
125
- """
126
- Execute multiple queries
127
-
128
- :param queries: list of queries
129
- :return: None
130
- """
131
-
132
- async with self._session_pool.connection() as connection:
133
- for item in queries:
134
- query = item[0]
135
- packed_values = item[1]
136
- if packed_values:
137
- await connection.execute(query, packed_values)
138
- else:
139
- await connection.execute(query)
140
-
141
- @retry
142
- async def execute_many(self, query: SQL | str, dictionary: list[dict]) -> None:
143
- """
144
- Execute many queries
145
-
146
- :param query: query
147
- :param dictionary: dictionary of values
148
- :return: None
149
- """
150
-
151
- async with self._session_pool.connection() as connection:
152
- await connection.executemany(query, dictionary)
153
-
154
- @retry
155
- async def fetch_data(self, query: SQL | str, packed_data=None):
156
- """
157
- Fetch the data from the query
158
-
159
- :param query: query
160
- :param packed_data: packed data
161
- :return: rows
162
- """
163
-
164
- async with self._session_pool.connection() as connection:
165
- cursor = connection.cursor()
166
- if packed_data:
167
- await cursor.execute(query, packed_data)
168
- else:
169
- await cursor.execute(query)
170
- rows = await cursor.fetchall()
171
- return rows
172
-
173
- @retry
174
- async def remove_matching_data(self, dfObj: pd.DataFrame, outputTableName: str, match_cols: list) -> None:
175
- """
176
- Remove matching data from the warehouse
177
-
178
- :param dfObj: DataFrame
179
- :param outputTableName: output table name
180
- :param match_cols: list of columns
181
- :return: None
182
- """
183
-
184
- df = dfObj[match_cols]
185
- param_list = []
186
- for column in match_cols:
187
- param_list.append(f"{column} = %({column})s")
188
- if len(param_list) > 1:
189
- params = ' AND '.join(param_list)
190
- else:
191
- params = param_list[0]
192
-
193
- main_dict = df.to_dict('records')
194
- query = """DELETE FROM {} WHERE {}""".format(outputTableName, params)
195
- await self.execute_many(query, main_dict)
196
-
197
- @retry
198
- async def export_DF_to_warehouse(self, dfObj: pd.DataFrame, outputTableName: str, columns: list, remove_nan=False) -> None:
199
- """
200
- Export the DataFrame to the warehouse
201
-
202
- :param dfObj: DataFrame
203
- :param outputTableName: output table name
204
- :param columns: list of columns
205
- :param remove_nan: remove NaN values
206
- :return: None
207
- """
208
-
209
- col = ', '.join(columns)
210
- param_list = []
211
- for column in columns:
212
- param_list.append(f"%({column})s")
213
- params = ', '.join(param_list)
214
-
215
- if remove_nan:
216
- dfObj = dfObj.replace({np.nan: None})
217
- main_dict = dfObj.to_dict('records')
218
-
219
- # if remove_nan:
220
- # for val, item in enumerate(main_dict):
221
- # for sub_item, value in item.items():
222
- # if pd.isna(value):
223
- # main_dict[val][sub_item] = None
224
- # else:
225
- # main_dict[val][sub_item] = value
226
-
227
- query = """INSERT INTO {} ({}) VALUES ({})""".format(outputTableName, col, params)
228
- await self.execute_many(query, main_dict)
229
-
230
- @retry
231
- async def truncate_table(self, tableName: str) -> None:
232
- """
233
- Truncate the table
234
-
235
- :param tableName: table name
236
- :return: None
237
- """
238
-
239
- truncateQuery = """TRUNCATE TABLE {}""".format(tableName)
240
- await self.execute(truncateQuery)
241
-
242
- @retry
243
- async def empty_table(self, tableName: str) -> None:
244
- """
245
- Empty the table
246
-
247
- :param tableName: table name
248
- :return: None
249
- """
250
-
251
- deleteQuery = """DELETE FROM {}""".format(tableName)
252
- await self.execute(deleteQuery)
@@ -1,25 +0,0 @@
1
- wcp_library/__init__.py,sha256=hwLbcu00uI6L_xjXO9-I0YcODl2WtIOkdNLoDcXv7zk,591
2
- wcp_library/async_credentials/__init__.py,sha256=ny6UitVV_xIecVzaWuHrJO9LpywBPke6u4C0F2wiM7o,1881
3
- wcp_library/async_credentials/api.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- wcp_library/async_credentials/oracle.py,sha256=MvC7wsHnSyAyPGnRVlH0dvvW2xk5ap_IAByoHX4rUWY,5436
5
- wcp_library/async_credentials/postgres.py,sha256=3wjqtLH0Nc-U80iscYnz5DV-9M2X4IjPW51C5MI2_tI,5297
6
- wcp_library/async_sql/__init__.py,sha256=m4eWmUGYUEDomhhOp1ScB2uSIXFsNUNO589o5RwWdyM,1035
7
- wcp_library/async_sql/oracle.py,sha256=RgPvHHZmD6s1BlttjZ112-0VZ45M2J-essDR5-vpiDw,7965
8
- wcp_library/async_sql/postgres.py,sha256=oy0lybtd4i6PsiDabU0Ll-I-amuykawAgtqHNJUyPkM,7493
9
- wcp_library/credentials/__init__.py,sha256=HRmg7mqcATeclIz3lZQjSR4nmK6aY6MK9-QXEYZoFrw,1857
10
- wcp_library/credentials/ftp.py,sha256=FRxKVWifz7olQIrSjDgkTqk7rmc7Zdwmkfq7b62DQY8,4965
11
- wcp_library/credentials/oracle.py,sha256=IJVGd10LH5LUNKUSFAbApi0sjR1AbloMJRHTuR9zFrQ,5095
12
- wcp_library/credentials/postgres.py,sha256=VROORbeH5D0MW-0LYrtAm4_L29qJd7A1o9VQuloqZYw,4956
13
- wcp_library/emailing.py,sha256=xqNly6Tmj-pvwl5bdys3gauZFDd4SuWCQYzGFNemv2Q,2496
14
- wcp_library/ftp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- wcp_library/ftp/ftp.py,sha256=EpyW0J2QIGxP8zVGD4VarA0hi4C2XAPDPF-0j2sRdpI,4350
16
- wcp_library/ftp/sftp.py,sha256=hykXGLGdxe7DYAxFdTwjPjTEOYuIpSMyK3NOiTQNUK0,4176
17
- wcp_library/informatica.py,sha256=IXZtk_9X1XLbOEwFrsyOwTgajQKvtXgANBHmuTOP3Kk,4064
18
- wcp_library/logging.py,sha256=e6gG7HFgUrMajUZs4Gs0atFfOJJmdmxN0GerfynNWlY,2061
19
- wcp_library/selenium_helper.py,sha256=rlphTXsUgnbaXZknY5nfQqxFhnc7UmrpzhV3hQ-cv7k,2509
20
- wcp_library/sql/__init__.py,sha256=CLlBEBrWVAwE79bUxuQiwikSrYH8m9QRYSJ2l0-ofsY,1003
21
- wcp_library/sql/oracle.py,sha256=hQxhQdT6C9Z1wZ-BGw2LYuoIgx5-ThJbEoo_ffOFSUc,7786
22
- wcp_library/sql/postgres.py,sha256=TE6U0EvKZ1BwQXRDdcX6SUu9z_9eno4RIf1pY0F1c0Q,7090
23
- wcp_library-1.2.9.dist-info/METADATA,sha256=6nNemO2bCgxhiWcSeuFqwZYUdkFmTtKK0Lt0SnLyDnI,1513
24
- wcp_library-1.2.9.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
25
- wcp_library-1.2.9.dist-info/RECORD,,