SQLPyHelper 0.1.2__py3-none-any.whl → 0.1.3__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/db_helper.py +113 -39
- {sqlpyhelper-0.1.2.dist-info → sqlpyhelper-0.1.3.dist-info}/METADATA +53 -48
- sqlpyhelper-0.1.3.dist-info/RECORD +7 -0
- sqlpyhelper-0.1.2.dist-info/RECORD +0 -7
- {sqlpyhelper-0.1.2.dist-info → sqlpyhelper-0.1.3.dist-info}/WHEEL +0 -0
- {sqlpyhelper-0.1.2.dist-info → sqlpyhelper-0.1.3.dist-info}/licenses/LICENSE +0 -0
- {sqlpyhelper-0.1.2.dist-info → sqlpyhelper-0.1.3.dist-info}/top_level.txt +0 -0
sqlpyhelper/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# Match the version in setup.py
|
|
2
|
-
__version__ = "0.1.
|
|
2
|
+
__version__ = "0.1.3"
|
sqlpyhelper/db_helper.py
CHANGED
|
@@ -56,24 +56,46 @@ class SQLPyHelper:
|
|
|
56
56
|
self.cursor.execute(query)
|
|
57
57
|
self.connection.commit()
|
|
58
58
|
except Exception as e:
|
|
59
|
-
|
|
59
|
+
if "server has gone away" in str(e): # Example check for MySQL lost connection
|
|
60
|
+
self.reconnect()
|
|
61
|
+
self.cursor.execute(query, params)
|
|
62
|
+
self.connection.commit()
|
|
63
|
+
else:
|
|
64
|
+
print(f"Error executing query: {e}")
|
|
60
65
|
|
|
61
66
|
def fetch_one(self):
|
|
62
|
-
|
|
67
|
+
"""Fetches a single row"""
|
|
68
|
+
try:
|
|
69
|
+
return self.cursor.fetchone()
|
|
70
|
+
except Exception as e:
|
|
71
|
+
print(f"Error fetching row: {e}")
|
|
72
|
+
return None
|
|
63
73
|
|
|
64
74
|
def fetch_all(self):
|
|
65
75
|
"""Fetches all rows from the last executed query"""
|
|
66
|
-
|
|
76
|
+
try:
|
|
77
|
+
return self.cursor.fetchall()
|
|
78
|
+
except Exception as e:
|
|
79
|
+
print(f"Error fetching rows: {e}")
|
|
80
|
+
return None
|
|
67
81
|
|
|
68
82
|
def fetch_by_param(self, table_name, column_name, value):
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
83
|
+
try:
|
|
84
|
+
query = f"SELECT * FROM {table_name} WHERE {column_name} = %s"
|
|
85
|
+
self.cursor.execute(query, (value,))
|
|
86
|
+
return self.cursor.fetchall()
|
|
87
|
+
except Exception as e:
|
|
88
|
+
print(f"Error fetching row(s): {e}")
|
|
89
|
+
return None
|
|
72
90
|
|
|
73
91
|
def close(self):
|
|
74
92
|
"""Closes the connection"""
|
|
75
|
-
|
|
76
|
-
|
|
93
|
+
try:
|
|
94
|
+
self.cursor.close()
|
|
95
|
+
self.connection.close()
|
|
96
|
+
except Exception as e:
|
|
97
|
+
print(f"Error closing connection: {e}")
|
|
98
|
+
return None
|
|
77
99
|
|
|
78
100
|
def create_table(self, table_name, columns):
|
|
79
101
|
"""
|
|
@@ -81,9 +103,13 @@ class SQLPyHelper:
|
|
|
81
103
|
Example:
|
|
82
104
|
columns = {'id': 'INTEGER PRIMARY KEY', 'name': 'TEXT', 'age': 'INTEGER'}
|
|
83
105
|
"""
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
106
|
+
try:
|
|
107
|
+
column_defs = ", ".join(f"{col} {dtype}" for col, dtype in columns.items())
|
|
108
|
+
query = f"CREATE TABLE {table_name} ({column_defs})"
|
|
109
|
+
self.execute_query(query)
|
|
110
|
+
except Exception as e:
|
|
111
|
+
print(f"Error creating table: {e}")
|
|
112
|
+
return None
|
|
87
113
|
|
|
88
114
|
def insert_bulk(self, table_name, data):
|
|
89
115
|
"""
|
|
@@ -91,12 +117,17 @@ class SQLPyHelper:
|
|
|
91
117
|
Example:
|
|
92
118
|
data = [{'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}]
|
|
93
119
|
"""
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
120
|
+
try:
|
|
121
|
+
columns = ", ".join(data[0].keys()) # Extract column names
|
|
122
|
+
placeholders = ", ".join(["%s" for _ in data[0].keys()]) # Generate placeholders
|
|
123
|
+
query = f"INSERT INTO {table_name} ({columns}) VALUES ({placeholders})"
|
|
124
|
+
values = [tuple(row.values()) for row in data]
|
|
125
|
+
self.cursor.executemany(query, values)
|
|
126
|
+
self.connection.commit()
|
|
127
|
+
|
|
128
|
+
except Exception as e:
|
|
129
|
+
print(f"Error inserting bulk rows: {e}")
|
|
130
|
+
return None
|
|
100
131
|
|
|
101
132
|
def backup_table(self, table_name, backup_file):
|
|
102
133
|
"""
|
|
@@ -104,32 +135,75 @@ class SQLPyHelper:
|
|
|
104
135
|
Example:
|
|
105
136
|
backup_table('users', 'users_backup.csv')
|
|
106
137
|
"""
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
138
|
+
try:
|
|
139
|
+
query = f"SELECT * FROM {table_name}"
|
|
140
|
+
self.execute_query(query)
|
|
141
|
+
rows = self.fetch_all()
|
|
142
|
+
|
|
143
|
+
with open(backup_file, mode="w", newline="") as file:
|
|
144
|
+
writer = csv.writer(file)
|
|
145
|
+
writer.writerow([desc[0] for desc in self.cursor.description]) # Column headers
|
|
146
|
+
writer.writerows(rows)
|
|
147
|
+
except Exception as e:
|
|
148
|
+
print(f"Error backing up table: {e}")
|
|
149
|
+
return None
|
|
110
150
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
151
|
+
def setup_connection_pool(self, min_conn=1, max_conn=5, pool_size=5):
|
|
152
|
+
"""Sets up connection pooling based on the database type"""
|
|
153
|
+
try:
|
|
154
|
+
if self.db_type == "postgres":
|
|
155
|
+
from psycopg2 import pool
|
|
156
|
+
self.pool = pool.SimpleConnectionPool(min_conn, max_conn,
|
|
157
|
+
host=self.host, user=self.user,
|
|
158
|
+
password=self.password, dbname=self.database)
|
|
159
|
+
|
|
160
|
+
elif self.db_type == "mysql":
|
|
161
|
+
import mysql.connector.pooling
|
|
162
|
+
self.pool = mysql.connector.pooling.MySQLConnectionPool(pool_name="mypool",
|
|
163
|
+
pool_size=pool_size, host=self.host,
|
|
164
|
+
user=self.user, password=self.password,
|
|
165
|
+
database=self.database)
|
|
166
|
+
|
|
167
|
+
elif self.db_type == "sqlserver":
|
|
168
|
+
import pyodbc
|
|
169
|
+
self.pool = [
|
|
170
|
+
pyodbc.connect(f"DRIVER={self.driver};SERVER={self.host};DATABASE={self.database};"
|
|
171
|
+
f"UID={self.user};PWD={self.password};ConnectionPooling=Yes")
|
|
172
|
+
for _ in range(pool_size)
|
|
173
|
+
]
|
|
174
|
+
|
|
175
|
+
elif self.db_type == "oracle":
|
|
176
|
+
import cx_Oracle
|
|
177
|
+
oracle_port = os.getenv("ORACLE_DB_PORT", "1521") # Default Oracle port
|
|
178
|
+
dsn = cx_Oracle.makedsn(self.host, oracle_port, self.oracle_sid)
|
|
179
|
+
self.pool = cx_Oracle.SessionPool(user=self.user, password=self.password, dsn=dsn,
|
|
180
|
+
min=min_conn, max=max_conn, increment=1, threaded=True)
|
|
115
181
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
"""
|
|
122
|
-
from psycopg2 import pool
|
|
123
|
-
self.pool = pool.SimpleConnectionPool(min_conn, max_conn,
|
|
124
|
-
host=self.host,
|
|
125
|
-
user=self.user,
|
|
126
|
-
password=self.password,
|
|
127
|
-
dbname=self.database)
|
|
182
|
+
else:
|
|
183
|
+
raise ValueError(f"Connection pooling not supported for {self.db_type}")
|
|
184
|
+
except Exception as e:
|
|
185
|
+
print(f"⚠️ Error setting up connection pool: {e}")
|
|
186
|
+
self.pool = None # Prevent broken pool usage
|
|
128
187
|
|
|
129
188
|
def get_connection_from_pool(self):
|
|
130
189
|
"""Fetches a connection from the pool."""
|
|
131
|
-
return self.pool.
|
|
190
|
+
return self.pool.get_connection()
|
|
132
191
|
|
|
133
|
-
def return_connection_to_pool(self
|
|
192
|
+
def return_connection_to_pool(self):
|
|
134
193
|
"""Returns a connection back to the pool."""
|
|
135
|
-
self.
|
|
194
|
+
self.connection.close()
|
|
195
|
+
|
|
196
|
+
def reconnect(self):
|
|
197
|
+
"""Reconnects to the database if connection is lost"""
|
|
198
|
+
try:
|
|
199
|
+
self.connection.close() # Close existing connection
|
|
200
|
+
self.__init__() # Reinitialize the connection
|
|
201
|
+
print("Database reconnected successfully.")
|
|
202
|
+
except Exception as e:
|
|
203
|
+
print(f"Error during reconnection: {e}")
|
|
204
|
+
|
|
205
|
+
def begin_transaction(self):
|
|
206
|
+
self.execute_query("START TRANSACTION")
|
|
207
|
+
|
|
208
|
+
def rollback_transaction(self):
|
|
209
|
+
self.execute_query("ROLLBACK")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: SQLPyHelper
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: A simple SQL database helper package for Python.
|
|
5
5
|
Author: Adebayo Olaonipekun
|
|
6
6
|
Author-email: pekunmi@live.com
|
|
@@ -38,9 +38,9 @@ Dynamic: requires-dist
|
|
|
38
38
|
Dynamic: requires-python
|
|
39
39
|
Dynamic: summary
|
|
40
40
|
|
|
41
|
-
# 📌 SQLPyHelper
|
|
41
|
+
# 📌 SQLPyHelper v.0.1.3 🚀
|
|
42
42
|
|
|
43
|
-
A Python library for simplified database interactions across **SQLite, PostgreSQL, MySQL, SQL Server, and Oracle**.
|
|
43
|
+
A Python library for simplified database interactions across **SQLite, PostgreSQL, MySQL, SQL Server, and Oracle**. SQLPyHelper provides an intuitive API for handling queries, connection pooling, transactions, logging, and backups efficiently.
|
|
44
44
|
|
|
45
45
|
## 📖 Table of Contents
|
|
46
46
|
- [🚀 Features](#-features)
|
|
@@ -53,17 +53,20 @@ A Python library for simplified database interactions across **SQLite, PostgreSQ
|
|
|
53
53
|
- [SQL Server Example](#sql-server-example)
|
|
54
54
|
- [Oracle Example](#oracle-example)
|
|
55
55
|
- [📂 Project Structure](#-project-structure)
|
|
56
|
+
- [📌 Available Methods in SQLPyHelper](#-available-methods-in-sqlpyhelper)
|
|
56
57
|
- [🌍 Contributing](#-contributing)
|
|
57
58
|
- [☕ Support the Project](#-support-the-project)
|
|
58
59
|
|
|
59
60
|
---
|
|
60
61
|
|
|
61
|
-
## 🚀 Features
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
## 🚀 Features in v0.1.3
|
|
63
|
+
✅ Unified connection pooling for multiple databases.
|
|
64
|
+
✅ Automatic reconnection for lost connections.
|
|
65
|
+
✅ Transaction support (BEGIN, ROLLBACK, COMMIT).
|
|
66
|
+
✅ Secure parameterized queries to prevent SQL injection.
|
|
67
|
+
✅ Bulk insertion & dynamic table creation.
|
|
68
|
+
✅ Logging & error handling for better debugging.
|
|
69
|
+
✅ CSV export & database backups.
|
|
67
70
|
|
|
68
71
|
---
|
|
69
72
|
## 📦 Installation
|
|
@@ -73,7 +76,7 @@ pip install sqlpyhelper
|
|
|
73
76
|
```
|
|
74
77
|
📌 Package on PyPI: [SQLPyHelper on PyPI](https://pypi.org/project/SQLPyHelper/)
|
|
75
78
|
|
|
76
|
-
|
|
79
|
+
For local development:
|
|
77
80
|
```sh
|
|
78
81
|
git clone https://github.com/adebayopeter/sqlpyhelper.git
|
|
79
82
|
cd sqlpyhelper
|
|
@@ -110,62 +113,46 @@ database = os.getenv("DB_NAME")
|
|
|
110
113
|
```
|
|
111
114
|
---
|
|
112
115
|
## 🛠 Usage Examples
|
|
113
|
-
###
|
|
116
|
+
### Initialize SQLPyHelper
|
|
114
117
|
```pycon
|
|
115
118
|
from sqlpyhelper.db_helper import SQLPyHelper
|
|
116
|
-
|
|
117
|
-
|
|
119
|
+
db = SQLPyHelper() # Auto-detects database type based on `DB_TYPE`
|
|
120
|
+
```
|
|
121
|
+
### SQLite Example
|
|
122
|
+
```pycon
|
|
118
123
|
db.execute_query("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
|
|
119
124
|
db.execute_query("INSERT INTO users (name) VALUES (?)", ("Alice",))
|
|
120
|
-
db.
|
|
121
|
-
print(db.fetch_all())
|
|
125
|
+
print(db.fetch_all()) # Expected Output: [(1, 'Alice')]
|
|
122
126
|
db.close()
|
|
123
127
|
```
|
|
124
128
|
### PostgreSQL Example
|
|
125
129
|
```pycon
|
|
126
|
-
db
|
|
127
|
-
db.execute_query("
|
|
128
|
-
db.
|
|
129
|
-
db.execute_query("
|
|
130
|
-
|
|
131
|
-
db.close()
|
|
130
|
+
db.execute_query("CREATE TABLE customers (id SERIAL PRIMARY KEY, name TEXT)")
|
|
131
|
+
db.execute_query("INSERT INTO customers (name) VALUES (%s)", ("Bob",))
|
|
132
|
+
db.begin_transaction()
|
|
133
|
+
db.execute_query("DELETE FROM customers WHERE name=%s", ("Bob",))
|
|
134
|
+
db.rollback_transaction() # Undo delete
|
|
132
135
|
```
|
|
133
136
|
### MySQL Example
|
|
134
|
-
```pycon
|
|
135
|
-
db
|
|
136
|
-
db.execute_query("
|
|
137
|
-
db.
|
|
138
|
-
db.execute_query("SELECT * FROM customers")
|
|
139
|
-
print(db.fetch_all())
|
|
140
|
-
db.close()
|
|
141
|
-
```
|
|
142
|
-
```pycon
|
|
143
|
-
db = SQLPyHelper()
|
|
144
|
-
|
|
145
|
-
# Fetch rows where customer_id = 3
|
|
146
|
-
customers = db.fetch_by_param("customers", "id", 3)
|
|
147
|
-
print(customers)
|
|
148
|
-
|
|
137
|
+
```pycon
|
|
138
|
+
db.execute_query("CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(100))")
|
|
139
|
+
db.execute_query("INSERT INTO users (id, name) VALUES (%s, %s)", (1, "Alice"))
|
|
140
|
+
print(db.fetch_by_param("users", "id", 1)) # Expected Output: [(1, 'Alice')]
|
|
149
141
|
db.close()
|
|
150
142
|
```
|
|
151
|
-
|
|
152
143
|
### SQL Server Example
|
|
153
144
|
```pycon
|
|
154
|
-
db
|
|
155
|
-
db.
|
|
156
|
-
db.
|
|
157
|
-
db.execute_query("SELECT * FROM orders")
|
|
158
|
-
print(db.fetch_all())
|
|
159
|
-
db.close()
|
|
145
|
+
db.execute_query("CREATE TABLE orders (order_id INT PRIMARY KEY, item NVARCHAR(100))")
|
|
146
|
+
db.insert_bulk("orders", [{"order_id": 1, "item": "Laptop"}, {"order_id": 2, "item": "Mouse"}])
|
|
147
|
+
db.backup_table("orders", "orders_backup.csv") # Export data to CSV
|
|
160
148
|
```
|
|
161
149
|
### Oracle Example
|
|
162
150
|
```pycon
|
|
163
|
-
db = SQLPyHelper()
|
|
164
151
|
db.execute_query("CREATE TABLE employees (id NUMBER PRIMARY KEY, name VARCHAR2(100))")
|
|
165
|
-
db.execute_query("INSERT INTO employees (id, name) VALUES (:1, :2)", (1, "
|
|
166
|
-
db.
|
|
167
|
-
|
|
168
|
-
db.
|
|
152
|
+
db.execute_query("INSERT INTO employees (id, name) VALUES (:1, :2)", (1, "Charlie"))
|
|
153
|
+
db.setup_connection_pool(min_conn=2, max_conn=10) # Enable pooling for better performance
|
|
154
|
+
conn = db.get_connection_from_pool()
|
|
155
|
+
db.return_connection_to_pool(conn)
|
|
169
156
|
```
|
|
170
157
|
|
|
171
158
|
## 📂 Project Structure
|
|
@@ -182,6 +169,24 @@ db.close()
|
|
|
182
169
|
├─ README.md
|
|
183
170
|
└─ requirements.txt
|
|
184
171
|
```
|
|
172
|
+
---
|
|
173
|
+
## 📌 Available Methods in SQLPyHelper
|
|
174
|
+
|
|
175
|
+
| Method | Description |
|
|
176
|
+
|--------|-------------|
|
|
177
|
+
| `execute_query(query, params=None)` | Executes a SQL query with optional parameters. |
|
|
178
|
+
| `fetch_one()` | Retrieves a **single row** from query results. |
|
|
179
|
+
| `fetch_all()` | Retrieves **all rows** from query results. |
|
|
180
|
+
| `fetch_by_param(table, column, value)` | Fetches **rows dynamically** based on a given parameter. |
|
|
181
|
+
| `create_table(table_name, columns_dict)` | Creates a table dynamically with a dictionary format. |
|
|
182
|
+
| `insert_bulk(table, data_list)` | Inserts **multiple rows at once** efficiently. |
|
|
183
|
+
| `backup_table(table, backup_file.csv)` | Exports table data to **CSV format**. |
|
|
184
|
+
| `setup_connection_pool()` | Initializes **database connection pooling**. |
|
|
185
|
+
| `get_connection_from_pool()` | Fetches a connection from the pool. |
|
|
186
|
+
| `return_connection_to_pool(conn)` | Returns connection back to pool. |
|
|
187
|
+
| `begin_transaction()` | Begins an **explicit transaction**. |
|
|
188
|
+
| `rollback_transaction()` | Rolls back **uncommitted transactions**. |
|
|
189
|
+
| `close()` | Closes the database connection safely. |
|
|
185
190
|
|
|
186
191
|
---
|
|
187
192
|
## 🌍 Contributing
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
sqlpyhelper/__init__.py,sha256=v4m1w8m6t3Ypvteu4Ukto47uZG_pAHHkBFcKjWrk__Q,54
|
|
2
|
+
sqlpyhelper/db_helper.py,sha256=hRgwzPM5Ze_xKwgphQLJovQmkVpVhKffmAa1C7Lje9g,8447
|
|
3
|
+
sqlpyhelper-0.1.3.dist-info/licenses/LICENSE,sha256=9XzXxZ_8mWFM9-2TlqyE3L69zvRf4VPY_xIzSj5iU-g,1076
|
|
4
|
+
sqlpyhelper-0.1.3.dist-info/METADATA,sha256=zYkK-eNm3BBm4T0bStWMSWdIR44pyWQgJOjUHh6lnQ8,7253
|
|
5
|
+
sqlpyhelper-0.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
+
sqlpyhelper-0.1.3.dist-info/top_level.txt,sha256=FrLqTmqTGDa8jHnnf2ZVkYO-gFvLXX9QonpUCE6wKGs,12
|
|
7
|
+
sqlpyhelper-0.1.3.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
sqlpyhelper/__init__.py,sha256=kJA4mgypZmLd3SnwwTNkVwB0yIJ8PKP4h9cjOCIPfTA,54
|
|
2
|
-
sqlpyhelper/db_helper.py,sha256=TT93q3f1EVjkgUSXA4iXCy9Uw5gdGuRbqH-Wl-8OjeI,5269
|
|
3
|
-
sqlpyhelper-0.1.2.dist-info/licenses/LICENSE,sha256=9XzXxZ_8mWFM9-2TlqyE3L69zvRf4VPY_xIzSj5iU-g,1076
|
|
4
|
-
sqlpyhelper-0.1.2.dist-info/METADATA,sha256=ATC92p-IcBVUFEBHKXqqMBkYC524FsdQpxDVBmhQ3JI,5954
|
|
5
|
-
sqlpyhelper-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
-
sqlpyhelper-0.1.2.dist-info/top_level.txt,sha256=FrLqTmqTGDa8jHnnf2ZVkYO-gFvLXX9QonpUCE6wKGs,12
|
|
7
|
-
sqlpyhelper-0.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|