SQLPyHelper 0.1.9__py3-none-any.whl → 0.2.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.
- sqlpyhelper/__init__.py +1 -1
- sqlpyhelper/async_helper.py +4 -4
- sqlpyhelper/db_helper.py +15 -11
- sqlpyhelper/migration.py +6 -6
- {sqlpyhelper-0.1.9.dist-info → sqlpyhelper-0.2.1.dist-info}/METADATA +1 -1
- sqlpyhelper-0.2.1.dist-info/RECORD +13 -0
- sqlpyhelper-0.1.9.dist-info/RECORD +0 -13
- {sqlpyhelper-0.1.9.dist-info → sqlpyhelper-0.2.1.dist-info}/WHEEL +0 -0
- {sqlpyhelper-0.1.9.dist-info → sqlpyhelper-0.2.1.dist-info}/entry_points.txt +0 -0
- {sqlpyhelper-0.1.9.dist-info → sqlpyhelper-0.2.1.dist-info}/licenses/LICENSE +0 -0
- {sqlpyhelper-0.1.9.dist-info → sqlpyhelper-0.2.1.dist-info}/top_level.txt +0 -0
sqlpyhelper/__init__.py
CHANGED
sqlpyhelper/async_helper.py
CHANGED
|
@@ -28,7 +28,7 @@ Example usage::
|
|
|
28
28
|
|
|
29
29
|
import logging
|
|
30
30
|
import os
|
|
31
|
-
from typing import Any, Optional
|
|
31
|
+
from typing import Any, List, Optional, Tuple
|
|
32
32
|
|
|
33
33
|
from dotenv import load_dotenv
|
|
34
34
|
|
|
@@ -190,7 +190,7 @@ class AsyncSQLPyHelper:
|
|
|
190
190
|
"No active connection. Call connect() or use async with."
|
|
191
191
|
)
|
|
192
192
|
|
|
193
|
-
def _adapt_query(self, query: str, args: tuple) ->
|
|
193
|
+
def _adapt_query(self, query: str, args: tuple) -> Tuple[str, tuple]:
|
|
194
194
|
"""
|
|
195
195
|
Adapt a query and its arguments for the active database driver.
|
|
196
196
|
|
|
@@ -320,7 +320,7 @@ class AsyncSQLPyHelper:
|
|
|
320
320
|
except Exception as e:
|
|
321
321
|
raise AsyncQueryError(f"fetch_one failed: {e}") from e
|
|
322
322
|
|
|
323
|
-
async def fetch_all(self, query: str, *args: Any) ->
|
|
323
|
+
async def fetch_all(self, query: str, *args: Any) -> List[Any]:
|
|
324
324
|
"""
|
|
325
325
|
Execute a SELECT query and return all rows.
|
|
326
326
|
|
|
@@ -409,7 +409,7 @@ class AsyncSQLPyHelper:
|
|
|
409
409
|
except Exception as e:
|
|
410
410
|
raise AsyncQueryError(f"fetch_val failed: {e}") from e
|
|
411
411
|
|
|
412
|
-
async def execute_many(self, query: str, args_list:
|
|
412
|
+
async def execute_many(self, query: str, args_list: List[tuple]) -> None:
|
|
413
413
|
"""
|
|
414
414
|
Execute a SQL statement multiple times with different parameters.
|
|
415
415
|
Efficient for bulk inserts::
|
sqlpyhelper/db_helper.py
CHANGED
|
@@ -2,7 +2,7 @@ import csv
|
|
|
2
2
|
import logging
|
|
3
3
|
import os
|
|
4
4
|
import re
|
|
5
|
-
from typing import Any, Literal, Optional
|
|
5
|
+
from typing import Any, Dict, List, Literal, Optional
|
|
6
6
|
|
|
7
7
|
from dotenv import load_dotenv
|
|
8
8
|
|
|
@@ -80,6 +80,7 @@ class SQLPyHelper:
|
|
|
80
80
|
self.port: Optional[str] = port or os.getenv("DB_PORT")
|
|
81
81
|
self.oracle_sid: Optional[str] = oracle_sid or os.getenv("ORACLE_SID")
|
|
82
82
|
self.pool: Any = None
|
|
83
|
+
self._in_transaction: bool = False
|
|
83
84
|
|
|
84
85
|
if not self.db_type or not self.database:
|
|
85
86
|
raise ValueError("Missing required database configuration.")
|
|
@@ -143,14 +144,14 @@ class SQLPyHelper:
|
|
|
143
144
|
self.cursor.execute(query, params)
|
|
144
145
|
else:
|
|
145
146
|
self.cursor.execute(query)
|
|
146
|
-
self.
|
|
147
|
+
if not self._in_transaction:
|
|
148
|
+
self.connection.commit()
|
|
147
149
|
except Exception as e:
|
|
148
|
-
if "server has gone away" in str(
|
|
149
|
-
e
|
|
150
|
-
): # Example check for MySQL lost connection
|
|
150
|
+
if "server has gone away" in str(e):
|
|
151
151
|
self.reconnect()
|
|
152
152
|
self.cursor.execute(query, params) # type: ignore[arg-type]
|
|
153
|
-
self.
|
|
153
|
+
if not self._in_transaction:
|
|
154
|
+
self.connection.commit()
|
|
154
155
|
else:
|
|
155
156
|
raise QueryError(f"Query failed: {e}") from e
|
|
156
157
|
|
|
@@ -161,7 +162,7 @@ class SQLPyHelper:
|
|
|
161
162
|
except Exception as e:
|
|
162
163
|
raise QueryError(f"Failed to fetch row: {e}") from e
|
|
163
164
|
|
|
164
|
-
def fetch_all(self) ->
|
|
165
|
+
def fetch_all(self) -> List[tuple]:
|
|
165
166
|
"""Fetches all rows from the last executed query"""
|
|
166
167
|
try:
|
|
167
168
|
return self.cursor.fetchall()
|
|
@@ -170,7 +171,7 @@ class SQLPyHelper:
|
|
|
170
171
|
|
|
171
172
|
def fetch_by_param(
|
|
172
173
|
self, table_name: str, column_name: str, value: Any
|
|
173
|
-
) ->
|
|
174
|
+
) -> List[tuple]:
|
|
174
175
|
"""Fetches rows from a table where a column matches the given value."""
|
|
175
176
|
try:
|
|
176
177
|
table_name = _validate_identifier(table_name)
|
|
@@ -190,7 +191,7 @@ class SQLPyHelper:
|
|
|
190
191
|
except Exception as e:
|
|
191
192
|
raise ConnectionError(f"Failed to close connection: {e}") from e
|
|
192
193
|
|
|
193
|
-
def create_table(self, table_name: str, columns:
|
|
194
|
+
def create_table(self, table_name: str, columns: Dict[str, str]) -> None:
|
|
194
195
|
"""
|
|
195
196
|
Creates a table dynamically using a dictionary format.
|
|
196
197
|
Example:
|
|
@@ -209,7 +210,7 @@ class SQLPyHelper:
|
|
|
209
210
|
except Exception as e:
|
|
210
211
|
raise QueryError(f"Failed to create table: {e}") from e
|
|
211
212
|
|
|
212
|
-
def insert_bulk(self, table_name: str, data:
|
|
213
|
+
def insert_bulk(self, table_name: str, data: List[Dict[str, Any]]) -> None:
|
|
213
214
|
"""
|
|
214
215
|
Inserts multiple rows at once.
|
|
215
216
|
Example:
|
|
@@ -350,6 +351,7 @@ class SQLPyHelper:
|
|
|
350
351
|
self.execute_query("BEGIN TRANSACTION")
|
|
351
352
|
elif self.db_type == "oracle":
|
|
352
353
|
pass # Oracle starts transactions implicitly on first DML statement
|
|
354
|
+
self._in_transaction = True
|
|
353
355
|
logger.info("Transaction started on %s database", self.db_type)
|
|
354
356
|
except Exception as e:
|
|
355
357
|
raise QueryError(f"Failed to begin transaction: {e}") from e
|
|
@@ -358,6 +360,7 @@ class SQLPyHelper:
|
|
|
358
360
|
"""Commit the current transaction."""
|
|
359
361
|
try:
|
|
360
362
|
self.connection.commit()
|
|
363
|
+
self._in_transaction = False
|
|
361
364
|
logger.info("Transaction committed on %s database", self.db_type)
|
|
362
365
|
except Exception as e:
|
|
363
366
|
raise QueryError(f"Failed to commit transaction: {e}") from e
|
|
@@ -366,11 +369,12 @@ class SQLPyHelper:
|
|
|
366
369
|
"""Roll back the current transaction."""
|
|
367
370
|
try:
|
|
368
371
|
self.connection.rollback()
|
|
372
|
+
self._in_transaction = False
|
|
369
373
|
logger.info("Transaction rolled back on %s database", self.db_type)
|
|
370
374
|
except Exception as e:
|
|
371
375
|
raise QueryError(f"Failed to rollback transaction: {e}") from e
|
|
372
376
|
|
|
373
|
-
def insert_dynamic(self, table: str, data:
|
|
377
|
+
def insert_dynamic(self, table: str, data: Dict[str, Any]) -> None:
|
|
374
378
|
"""
|
|
375
379
|
Dynamically constructs and executes an INSERT query with database-specific placeholders.
|
|
376
380
|
"""
|
sqlpyhelper/migration.py
CHANGED
|
@@ -24,7 +24,7 @@ Example usage::
|
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
26
|
import logging
|
|
27
|
-
from typing import Any, Optional
|
|
27
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
28
28
|
|
|
29
29
|
logger = logging.getLogger("sqlpyhelper.migration")
|
|
30
30
|
|
|
@@ -41,7 +41,7 @@ class MigrationError(Exception):
|
|
|
41
41
|
# Generic types are normalised from the source cursor description.
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
_TYPE_MAP:
|
|
44
|
+
_TYPE_MAP: Dict[str, Dict[str, str]] = {
|
|
45
45
|
"sqlite": {
|
|
46
46
|
"integer": "INTEGER",
|
|
47
47
|
"real": "REAL",
|
|
@@ -149,7 +149,7 @@ def _map_type(raw_type: Optional[str], target_db: str) -> str:
|
|
|
149
149
|
return target_types.get(generic, "TEXT")
|
|
150
150
|
|
|
151
151
|
|
|
152
|
-
def _get_column_info(source: Any, table: str) ->
|
|
152
|
+
def _get_column_info(source: Any, table: str) -> List[Tuple[str, str]]:
|
|
153
153
|
"""
|
|
154
154
|
Return a list of (column_name, raw_type_string) tuples
|
|
155
155
|
by inspecting the source database schema.
|
|
@@ -216,7 +216,7 @@ def _get_column_info(source: Any, table: str) -> list[tuple[str, str]]:
|
|
|
216
216
|
|
|
217
217
|
def _build_create_table_sql(
|
|
218
218
|
table: str,
|
|
219
|
-
columns:
|
|
219
|
+
columns: List[Tuple[str, str]],
|
|
220
220
|
target_db: str,
|
|
221
221
|
) -> str:
|
|
222
222
|
"""Build a CREATE TABLE IF NOT EXISTS statement for the target database."""
|
|
@@ -228,7 +228,7 @@ def _build_create_table_sql(
|
|
|
228
228
|
|
|
229
229
|
def _build_insert_sql(
|
|
230
230
|
table: str,
|
|
231
|
-
column_names:
|
|
231
|
+
column_names: List[str],
|
|
232
232
|
target_db: str,
|
|
233
233
|
) -> str:
|
|
234
234
|
"""Build a parameterised INSERT statement for the target database."""
|
|
@@ -250,7 +250,7 @@ def migrate_table(
|
|
|
250
250
|
create_table: bool = True,
|
|
251
251
|
batch_size: int = 500,
|
|
252
252
|
truncate_target: bool = False,
|
|
253
|
-
) ->
|
|
253
|
+
) -> Dict[str, Any]:
|
|
254
254
|
"""
|
|
255
255
|
Migrate a table from one database to another.
|
|
256
256
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
sqlpyhelper/__init__.py,sha256=bQLc1BMk3n5DyZ_BlmBsZOzfCqdybgerRj85WKfV5Co,370
|
|
2
|
+
sqlpyhelper/async_helper.py,sha256=iHQKhyZtfi4Dfg7ZTjQRGYKg5NCMbtWCVHZCS-V9348,21486
|
|
3
|
+
sqlpyhelper/automation_utils.py,sha256=pC6pH6bJ-k8iPVeHJ4gUiwEe822dasmKg53ya9bMxyE,5381
|
|
4
|
+
sqlpyhelper/cli.py,sha256=yj0kWJu3oh_JLnmi0L7a5ing2_0x4CQGOKSOhZLAtoY,5646
|
|
5
|
+
sqlpyhelper/db_helper.py,sha256=vMNs8IIjNO6PdN9idcZGYWudF2AnnYm3OrE9YYzwc3Q,14421
|
|
6
|
+
sqlpyhelper/migration.py,sha256=vsEnBIvhNWn0srzlcTj_uxUt7ZMxjDpU_s1CM4txy4U,11692
|
|
7
|
+
sqlpyhelper/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
sqlpyhelper-0.2.1.dist-info/licenses/LICENSE,sha256=9XzXxZ_8mWFM9-2TlqyE3L69zvRf4VPY_xIzSj5iU-g,1076
|
|
9
|
+
sqlpyhelper-0.2.1.dist-info/METADATA,sha256=7SD-1XaGrh4bjC7VLbhzgn9ZokdUsR_D6j0jwj24Ogk,11607
|
|
10
|
+
sqlpyhelper-0.2.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
11
|
+
sqlpyhelper-0.2.1.dist-info/entry_points.txt,sha256=uAzSqwkAbbJqQUKHlPNwOebTJVA0FqkOvn2CRP6xSz8,52
|
|
12
|
+
sqlpyhelper-0.2.1.dist-info/top_level.txt,sha256=FrLqTmqTGDa8jHnnf2ZVkYO-gFvLXX9QonpUCE6wKGs,12
|
|
13
|
+
sqlpyhelper-0.2.1.dist-info/RECORD,,
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
sqlpyhelper/__init__.py,sha256=8oatB3lhbYVLzbkCIDrlE1mTJVljs2GeNuUG34_vYd0,370
|
|
2
|
-
sqlpyhelper/async_helper.py,sha256=beq0wKxDl7Qv-CW_qA1-h_DPhDpC1CQHdstnKO-4FSI,21473
|
|
3
|
-
sqlpyhelper/automation_utils.py,sha256=pC6pH6bJ-k8iPVeHJ4gUiwEe822dasmKg53ya9bMxyE,5381
|
|
4
|
-
sqlpyhelper/cli.py,sha256=yj0kWJu3oh_JLnmi0L7a5ing2_0x4CQGOKSOhZLAtoY,5646
|
|
5
|
-
sqlpyhelper/db_helper.py,sha256=SrXro_-ki5AT_Yj6u1k5-aUZYq-d2QXeQPXURXqUMLk,14223
|
|
6
|
-
sqlpyhelper/migration.py,sha256=byAn7ToVgIB8tl1N39DB0MbHigjH2l-qX7QSskgzzTg,11673
|
|
7
|
-
sqlpyhelper/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
sqlpyhelper-0.1.9.dist-info/licenses/LICENSE,sha256=9XzXxZ_8mWFM9-2TlqyE3L69zvRf4VPY_xIzSj5iU-g,1076
|
|
9
|
-
sqlpyhelper-0.1.9.dist-info/METADATA,sha256=TTa0zKb4o_Zuf9x1j63Xg15vE9rUBbgDUnSjJHi0Hq0,11607
|
|
10
|
-
sqlpyhelper-0.1.9.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
11
|
-
sqlpyhelper-0.1.9.dist-info/entry_points.txt,sha256=uAzSqwkAbbJqQUKHlPNwOebTJVA0FqkOvn2CRP6xSz8,52
|
|
12
|
-
sqlpyhelper-0.1.9.dist-info/top_level.txt,sha256=FrLqTmqTGDa8jHnnf2ZVkYO-gFvLXX9QonpUCE6wKGs,12
|
|
13
|
-
sqlpyhelper-0.1.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|