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 CHANGED
@@ -1,2 +1,2 @@
1
1
  # Match the version in setup.py
2
- __version__ = "0.1.2"
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
- print(f"Error executing query: {e}")
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
- return self.cursor.fetchone()
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
- return self.cursor.fetchall()
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
- query = f"SELECT * FROM {table_name} WHERE {column_name} = %s"
70
- self.cursor.execute(query, (value,))
71
- return self.cursor.fetchall() # Fetch matching rows
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
- self.cursor.close()
76
- self.connection.close()
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
- column_defs = ", ".join(f"{col} {dtype}" for col, dtype in columns.items())
85
- query = f"CREATE TABLE {table_name} ({column_defs})"
86
- self.execute_query(query)
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
- columns = ", ".join(data[0].keys()) # Extract column names
95
- placeholders = ", ".join(["%s" for _ in data[0].keys()]) # Generate placeholders
96
- query = f"INSERT INTO {table_name} ({columns}) VALUES ({placeholders})"
97
- values = [tuple(row.values()) for row in data] # Convert dictionaries to tuples
98
- self.cursor.executemany(query, values)
99
- self.connection.commit()
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
- query = f"SELECT * FROM {table_name}"
108
- self.execute_query(query)
109
- rows = self.fetch_all()
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
- with open(backup_file, mode="w", newline="") as file:
112
- writer = csv.writer(file)
113
- writer.writerow([desc[0] for desc in self.cursor.description]) # Column headers
114
- writer.writerows(rows)
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
- def setup_postgres_pool(self, min_conn=1, max_conn=5):
117
- """
118
- Creates a connection pool for PostgreSQL.
119
- Example:
120
- setup_postgres_pool(min_conn=2, max_conn=10)
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.getconn()
190
+ return self.pool.get_connection()
132
191
 
133
- def return_connection_to_pool(self, conn):
192
+ def return_connection_to_pool(self):
134
193
  """Returns a connection back to the pool."""
135
- self.pool.putconn(conn)
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.2
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**. This open-source package provides an intuitive API for handling database operations efficiently.
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
- - **Unified Interface** for multiple databases
63
- - **Connection pooling support** for PostgreSQL
64
- - **Bulk insertion & dynamic table creation**
65
- - **Automated logging & query execution**
66
- - **CSV export & backup functionality**
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
- Or, if working from source:
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
- ### SQLite Example
116
+ ### Initialize SQLPyHelper
114
117
  ```pycon
115
118
  from sqlpyhelper.db_helper import SQLPyHelper
116
-
117
- db = SQLPyHelper()
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.execute_query("SELECT * FROM users")
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 = SQLPyHelper()
127
- db.execute_query("CREATE TABLE IF NOT EXISTS employees (id SERIAL PRIMARY KEY, name VARCHAR(100))")
128
- db.execute_query("INSERT INTO employees (name) VALUES (%s)", ("Charlie",))
129
- db.execute_query("SELECT * FROM employees")
130
- print(db.fetch_all())
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 = SQLPyHelper()
136
- db.execute_query("CREATE TABLE IF NOT EXISTS customers (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100))")
137
- db.execute_query("INSERT INTO customers (name) VALUES (%s)", ("David",))
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 = SQLPyHelper()
155
- db.execute_query("CREATE TABLE IF NOT EXISTS orders (id INT PRIMARY KEY, product VARCHAR(100))")
156
- db.execute_query("INSERT INTO orders (id, product) VALUES (?, ?)", (1, "Laptop"))
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, "Emily"))
166
- db.execute_query("SELECT * FROM employees")
167
- print(db.fetch_all())
168
- db.close()
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,,