SQLPyHelper 0.1.1__tar.gz → 0.1.3__tar.gz

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,12 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: SQLPyHelper
3
- Version: 0.1.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
7
7
  Classifier: Programming Language :: Python :: 3
8
- Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Topic :: Database :: Database Engines/Servers
9
11
  Classifier: Operating System :: OS Independent
12
+ Classifier: License :: OSI Approved :: MIT License
10
13
  Requires-Python: >=3.8
11
14
  Description-Content-Type: text/markdown
12
15
  License-File: LICENSE
@@ -15,19 +18,29 @@ Requires-Dist: mysql-connector-python
15
18
  Requires-Dist: pyodbc
16
19
  Requires-Dist: cx_Oracle
17
20
  Requires-Dist: python-dotenv
21
+ Provides-Extra: mysql
22
+ Requires-Dist: mysql-connector-python; extra == "mysql"
23
+ Provides-Extra: postgres
24
+ Requires-Dist: psycopg2; extra == "postgres"
25
+ Provides-Extra: oracle
26
+ Requires-Dist: cx_Oracle; extra == "oracle"
27
+ Provides-Extra: sqlserver
28
+ Requires-Dist: pyodbc; extra == "sqlserver"
29
+ Provides-Extra: sqlite
18
30
  Dynamic: author
19
31
  Dynamic: author-email
20
32
  Dynamic: classifier
21
33
  Dynamic: description
22
34
  Dynamic: description-content-type
23
35
  Dynamic: license-file
36
+ Dynamic: provides-extra
24
37
  Dynamic: requires-dist
25
38
  Dynamic: requires-python
26
39
  Dynamic: summary
27
40
 
28
- # 📌 SQLPyHelper
41
+ # 📌 SQLPyHelper v.0.1.3 🚀
29
42
 
30
- 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.
31
44
 
32
45
  ## 📖 Table of Contents
33
46
  - [🚀 Features](#-features)
@@ -40,24 +53,30 @@ A Python library for simplified database interactions across **SQLite, PostgreSQ
40
53
  - [SQL Server Example](#sql-server-example)
41
54
  - [Oracle Example](#oracle-example)
42
55
  - [📂 Project Structure](#-project-structure)
56
+ - [📌 Available Methods in SQLPyHelper](#-available-methods-in-sqlpyhelper)
43
57
  - [🌍 Contributing](#-contributing)
44
58
  - [☕ Support the Project](#-support-the-project)
45
59
 
46
60
  ---
47
61
 
48
- ## 🚀 Features
49
- - **Unified Interface** for multiple databases
50
- - **Connection pooling support** for PostgreSQL
51
- - **Bulk insertion & dynamic table creation**
52
- - **Automated logging & query execution**
53
- - **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.
54
70
 
55
71
  ---
56
72
  ## 📦 Installation
73
+ #### Install via PyPI:
57
74
  ```sh
58
75
  pip install sqlpyhelper
59
76
  ```
60
- Or, if working from source:
77
+ 📌 Package on PyPI: [SQLPyHelper on PyPI](https://pypi.org/project/SQLPyHelper/)
78
+
79
+ For local development:
61
80
  ```sh
62
81
  git clone https://github.com/adebayopeter/sqlpyhelper.git
63
82
  cd sqlpyhelper
@@ -75,11 +94,10 @@ DB_TYPE=postgres
75
94
  DB_HOST=localhost
76
95
  DB_USER=your_user
77
96
  DB_PASSWORD=your_secure_password
78
- DB_NAME=test_db
79
- DB_PORT=5432
97
+ DB_NAME=database_name
80
98
  DB_DRIVER={ODBC Driver 17 for SQL Server}
81
99
  ORACLE_SID=XE
82
- ORACLE_PORT=1521
100
+ ORACLE_DB_PORT=1521
83
101
  ```
84
102
  ### Loading `.env` in Code
85
103
  ```pycon
@@ -95,52 +113,46 @@ database = os.getenv("DB_NAME")
95
113
  ```
96
114
  ---
97
115
  ## 🛠 Usage Examples
98
- ### SQLite Example
116
+ ### Initialize SQLPyHelper
99
117
  ```pycon
100
118
  from sqlpyhelper.db_helper import SQLPyHelper
101
-
102
- db = SQLPyHelper()
119
+ db = SQLPyHelper() # Auto-detects database type based on `DB_TYPE`
120
+ ```
121
+ ### SQLite Example
122
+ ```pycon
103
123
  db.execute_query("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
104
124
  db.execute_query("INSERT INTO users (name) VALUES (?)", ("Alice",))
105
- db.execute_query("SELECT * FROM users")
106
- print(db.fetch_all())
125
+ print(db.fetch_all()) # Expected Output: [(1, 'Alice')]
107
126
  db.close()
108
127
  ```
109
128
  ### PostgreSQL Example
110
129
  ```pycon
111
- db = SQLPyHelper()
112
- db.execute_query("CREATE TABLE IF NOT EXISTS employees (id SERIAL PRIMARY KEY, name VARCHAR(100))")
113
- db.execute_query("INSERT INTO employees (name) VALUES (%s)", ("Charlie",))
114
- db.execute_query("SELECT * FROM employees")
115
- print(db.fetch_all())
116
- 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
117
135
  ```
118
136
  ### MySQL Example
119
- ```pycon
120
- db = SQLPyHelper()
121
- db.execute_query("CREATE TABLE IF NOT EXISTS customers (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100))")
122
- db.execute_query("INSERT INTO customers (name) VALUES (%s)", ("David",))
123
- db.execute_query("SELECT * FROM customers")
124
- print(db.fetch_all())
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')]
125
141
  db.close()
126
142
  ```
127
143
  ### SQL Server Example
128
144
  ```pycon
129
- db = SQLPyHelper()
130
- db.execute_query("CREATE TABLE IF NOT EXISTS orders (id INT PRIMARY KEY, product VARCHAR(100))")
131
- db.execute_query("INSERT INTO orders (id, product) VALUES (?, ?)", (1, "Laptop"))
132
- db.execute_query("SELECT * FROM orders")
133
- print(db.fetch_all())
134
- 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
135
148
  ```
136
149
  ### Oracle Example
137
150
  ```pycon
138
- db = SQLPyHelper()
139
151
  db.execute_query("CREATE TABLE employees (id NUMBER PRIMARY KEY, name VARCHAR2(100))")
140
- db.execute_query("INSERT INTO employees (id, name) VALUES (:1, :2)", (1, "Emily"))
141
- db.execute_query("SELECT * FROM employees")
142
- print(db.fetch_all())
143
- 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)
144
156
  ```
145
157
 
146
158
  ## 📂 Project Structure
@@ -157,6 +169,24 @@ db.close()
157
169
  ├─ README.md
158
170
  └─ requirements.txt
159
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. |
160
190
 
161
191
  ---
162
192
  ## 🌍 Contributing
@@ -0,0 +1,176 @@
1
+ # 📌 SQLPyHelper v.0.1.3 🚀
2
+
3
+ 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.
4
+
5
+ ## 📖 Table of Contents
6
+ - [🚀 Features](#-features)
7
+ - [📦 Installation](#-installation)
8
+ - [⚙️ Setup Using `.env`](#️-setup-using-env)
9
+ - [🛠 Usage Examples](#-usage-examples)
10
+ - [SQLite Example](#sqlite-example)
11
+ - [PostgreSQL Example](#postgresql-example)
12
+ - [MySQL Example](#mysql-example)
13
+ - [SQL Server Example](#sql-server-example)
14
+ - [Oracle Example](#oracle-example)
15
+ - [📂 Project Structure](#-project-structure)
16
+ - [📌 Available Methods in SQLPyHelper](#-available-methods-in-sqlpyhelper)
17
+ - [🌍 Contributing](#-contributing)
18
+ - [☕ Support the Project](#-support-the-project)
19
+
20
+ ---
21
+
22
+ ## 🚀 Features in v0.1.3
23
+ ✅ Unified connection pooling for multiple databases.
24
+ ✅ Automatic reconnection for lost connections.
25
+ ✅ Transaction support (BEGIN, ROLLBACK, COMMIT).
26
+ ✅ Secure parameterized queries to prevent SQL injection.
27
+ ✅ Bulk insertion & dynamic table creation.
28
+ ✅ Logging & error handling for better debugging.
29
+ ✅ CSV export & database backups.
30
+
31
+ ---
32
+ ## 📦 Installation
33
+ #### Install via PyPI:
34
+ ```sh
35
+ pip install sqlpyhelper
36
+ ```
37
+ 📌 Package on PyPI: [SQLPyHelper on PyPI](https://pypi.org/project/SQLPyHelper/)
38
+
39
+ For local development:
40
+ ```sh
41
+ git clone https://github.com/adebayopeter/sqlpyhelper.git
42
+ cd sqlpyhelper
43
+ pip install -r requirements.txt
44
+ ```
45
+
46
+ ---
47
+
48
+ ## ⚙️ Setup Using `.env`
49
+ Create a `.env` file in your project root to manage database configurations securely by renaming `.env_example`.
50
+
51
+ ```sh
52
+ # .env_example (Rename to .env)
53
+ DB_TYPE=postgres
54
+ DB_HOST=localhost
55
+ DB_USER=your_user
56
+ DB_PASSWORD=your_secure_password
57
+ DB_NAME=database_name
58
+ DB_DRIVER={ODBC Driver 17 for SQL Server}
59
+ ORACLE_SID=XE
60
+ ORACLE_DB_PORT=1521
61
+ ```
62
+ ### Loading `.env` in Code
63
+ ```pycon
64
+ from dotenv import load_dotenv
65
+ import os
66
+
67
+ load_dotenv()
68
+ db_type = os.getenv("DB_TYPE")
69
+ host = os.getenv("DB_HOST")
70
+ user = os.getenv("DB_USER")
71
+ password = os.getenv("DB_PASSWORD")
72
+ database = os.getenv("DB_NAME")
73
+ ```
74
+ ---
75
+ ## 🛠 Usage Examples
76
+ ### Initialize SQLPyHelper
77
+ ```pycon
78
+ from sqlpyhelper.db_helper import SQLPyHelper
79
+ db = SQLPyHelper() # Auto-detects database type based on `DB_TYPE`
80
+ ```
81
+ ### SQLite Example
82
+ ```pycon
83
+ db.execute_query("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
84
+ db.execute_query("INSERT INTO users (name) VALUES (?)", ("Alice",))
85
+ print(db.fetch_all()) # Expected Output: [(1, 'Alice')]
86
+ db.close()
87
+ ```
88
+ ### PostgreSQL Example
89
+ ```pycon
90
+ db.execute_query("CREATE TABLE customers (id SERIAL PRIMARY KEY, name TEXT)")
91
+ db.execute_query("INSERT INTO customers (name) VALUES (%s)", ("Bob",))
92
+ db.begin_transaction()
93
+ db.execute_query("DELETE FROM customers WHERE name=%s", ("Bob",))
94
+ db.rollback_transaction() # Undo delete
95
+ ```
96
+ ### MySQL Example
97
+ ```pycon
98
+ db.execute_query("CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(100))")
99
+ db.execute_query("INSERT INTO users (id, name) VALUES (%s, %s)", (1, "Alice"))
100
+ print(db.fetch_by_param("users", "id", 1)) # Expected Output: [(1, 'Alice')]
101
+ db.close()
102
+ ```
103
+ ### SQL Server Example
104
+ ```pycon
105
+ db.execute_query("CREATE TABLE orders (order_id INT PRIMARY KEY, item NVARCHAR(100))")
106
+ db.insert_bulk("orders", [{"order_id": 1, "item": "Laptop"}, {"order_id": 2, "item": "Mouse"}])
107
+ db.backup_table("orders", "orders_backup.csv") # Export data to CSV
108
+ ```
109
+ ### Oracle Example
110
+ ```pycon
111
+ db.execute_query("CREATE TABLE employees (id NUMBER PRIMARY KEY, name VARCHAR2(100))")
112
+ db.execute_query("INSERT INTO employees (id, name) VALUES (:1, :2)", (1, "Charlie"))
113
+ db.setup_connection_pool(min_conn=2, max_conn=10) # Enable pooling for better performance
114
+ conn = db.get_connection_from_pool()
115
+ db.return_connection_to_pool(conn)
116
+ ```
117
+
118
+ ## 📂 Project Structure
119
+ ```
120
+ 📦 SQLPyHelper/
121
+ ├─ sqlpyhelper/
122
+ │  ├─ __init__.py
123
+ │  └─ db_helper.py
124
+ ├─ tests/
125
+ │  └─ test_sqlpyhelper.py
126
+ ├─ .env_example
127
+ ├─ .gitignore
128
+ ├─ setup.py
129
+ ├─ README.md
130
+ └─ requirements.txt
131
+ ```
132
+ ---
133
+ ## 📌 Available Methods in SQLPyHelper
134
+
135
+ | Method | Description |
136
+ |--------|-------------|
137
+ | `execute_query(query, params=None)` | Executes a SQL query with optional parameters. |
138
+ | `fetch_one()` | Retrieves a **single row** from query results. |
139
+ | `fetch_all()` | Retrieves **all rows** from query results. |
140
+ | `fetch_by_param(table, column, value)` | Fetches **rows dynamically** based on a given parameter. |
141
+ | `create_table(table_name, columns_dict)` | Creates a table dynamically with a dictionary format. |
142
+ | `insert_bulk(table, data_list)` | Inserts **multiple rows at once** efficiently. |
143
+ | `backup_table(table, backup_file.csv)` | Exports table data to **CSV format**. |
144
+ | `setup_connection_pool()` | Initializes **database connection pooling**. |
145
+ | `get_connection_from_pool()` | Fetches a connection from the pool. |
146
+ | `return_connection_to_pool(conn)` | Returns connection back to pool. |
147
+ | `begin_transaction()` | Begins an **explicit transaction**. |
148
+ | `rollback_transaction()` | Rolls back **uncommitted transactions**. |
149
+ | `close()` | Closes the database connection safely. |
150
+
151
+ ---
152
+ ## 🌍 Contributing
153
+ We welcome contributions from the **open-source community**! Follow these steps to contribute:
154
+
155
+ 1. Fork the repo: [SQLPyHelper GitHub Repository](https://github.com/adebayopeter/sqlpyhelper)
156
+ 2. Clone your fork:
157
+ ```sh
158
+ git clone https://github.com/adebayopeter/sqlpyhelper.git
159
+ ```
160
+ 3. Create a new branch:
161
+ ```sh
162
+ git checkout -b feature-new-functionality
163
+ ```
164
+ 4. Make changes, commit, and push:
165
+ ```sh
166
+ git commit -m "Added new feature"
167
+ git push origin feature-new-functionality
168
+ ```
169
+ 5. Submit a Pull Request!
170
+
171
+ ---
172
+ ## ☕ Support the Project
173
+
174
+ If you find SQLPyHelper useful, consider buying me a coffee to support continued development!
175
+ Donate Here: [PayPal](https://paypal.me/adebayopeter?country.x=GB&locale.x=en_GB)
176
+ ---
@@ -1,12 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: SQLPyHelper
3
- Version: 0.1.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
7
7
  Classifier: Programming Language :: Python :: 3
8
- Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Topic :: Database :: Database Engines/Servers
9
11
  Classifier: Operating System :: OS Independent
12
+ Classifier: License :: OSI Approved :: MIT License
10
13
  Requires-Python: >=3.8
11
14
  Description-Content-Type: text/markdown
12
15
  License-File: LICENSE
@@ -15,19 +18,29 @@ Requires-Dist: mysql-connector-python
15
18
  Requires-Dist: pyodbc
16
19
  Requires-Dist: cx_Oracle
17
20
  Requires-Dist: python-dotenv
21
+ Provides-Extra: mysql
22
+ Requires-Dist: mysql-connector-python; extra == "mysql"
23
+ Provides-Extra: postgres
24
+ Requires-Dist: psycopg2; extra == "postgres"
25
+ Provides-Extra: oracle
26
+ Requires-Dist: cx_Oracle; extra == "oracle"
27
+ Provides-Extra: sqlserver
28
+ Requires-Dist: pyodbc; extra == "sqlserver"
29
+ Provides-Extra: sqlite
18
30
  Dynamic: author
19
31
  Dynamic: author-email
20
32
  Dynamic: classifier
21
33
  Dynamic: description
22
34
  Dynamic: description-content-type
23
35
  Dynamic: license-file
36
+ Dynamic: provides-extra
24
37
  Dynamic: requires-dist
25
38
  Dynamic: requires-python
26
39
  Dynamic: summary
27
40
 
28
- # 📌 SQLPyHelper
41
+ # 📌 SQLPyHelper v.0.1.3 🚀
29
42
 
30
- 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.
31
44
 
32
45
  ## 📖 Table of Contents
33
46
  - [🚀 Features](#-features)
@@ -40,24 +53,30 @@ A Python library for simplified database interactions across **SQLite, PostgreSQ
40
53
  - [SQL Server Example](#sql-server-example)
41
54
  - [Oracle Example](#oracle-example)
42
55
  - [📂 Project Structure](#-project-structure)
56
+ - [📌 Available Methods in SQLPyHelper](#-available-methods-in-sqlpyhelper)
43
57
  - [🌍 Contributing](#-contributing)
44
58
  - [☕ Support the Project](#-support-the-project)
45
59
 
46
60
  ---
47
61
 
48
- ## 🚀 Features
49
- - **Unified Interface** for multiple databases
50
- - **Connection pooling support** for PostgreSQL
51
- - **Bulk insertion & dynamic table creation**
52
- - **Automated logging & query execution**
53
- - **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.
54
70
 
55
71
  ---
56
72
  ## 📦 Installation
73
+ #### Install via PyPI:
57
74
  ```sh
58
75
  pip install sqlpyhelper
59
76
  ```
60
- Or, if working from source:
77
+ 📌 Package on PyPI: [SQLPyHelper on PyPI](https://pypi.org/project/SQLPyHelper/)
78
+
79
+ For local development:
61
80
  ```sh
62
81
  git clone https://github.com/adebayopeter/sqlpyhelper.git
63
82
  cd sqlpyhelper
@@ -75,11 +94,10 @@ DB_TYPE=postgres
75
94
  DB_HOST=localhost
76
95
  DB_USER=your_user
77
96
  DB_PASSWORD=your_secure_password
78
- DB_NAME=test_db
79
- DB_PORT=5432
97
+ DB_NAME=database_name
80
98
  DB_DRIVER={ODBC Driver 17 for SQL Server}
81
99
  ORACLE_SID=XE
82
- ORACLE_PORT=1521
100
+ ORACLE_DB_PORT=1521
83
101
  ```
84
102
  ### Loading `.env` in Code
85
103
  ```pycon
@@ -95,52 +113,46 @@ database = os.getenv("DB_NAME")
95
113
  ```
96
114
  ---
97
115
  ## 🛠 Usage Examples
98
- ### SQLite Example
116
+ ### Initialize SQLPyHelper
99
117
  ```pycon
100
118
  from sqlpyhelper.db_helper import SQLPyHelper
101
-
102
- db = SQLPyHelper()
119
+ db = SQLPyHelper() # Auto-detects database type based on `DB_TYPE`
120
+ ```
121
+ ### SQLite Example
122
+ ```pycon
103
123
  db.execute_query("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
104
124
  db.execute_query("INSERT INTO users (name) VALUES (?)", ("Alice",))
105
- db.execute_query("SELECT * FROM users")
106
- print(db.fetch_all())
125
+ print(db.fetch_all()) # Expected Output: [(1, 'Alice')]
107
126
  db.close()
108
127
  ```
109
128
  ### PostgreSQL Example
110
129
  ```pycon
111
- db = SQLPyHelper()
112
- db.execute_query("CREATE TABLE IF NOT EXISTS employees (id SERIAL PRIMARY KEY, name VARCHAR(100))")
113
- db.execute_query("INSERT INTO employees (name) VALUES (%s)", ("Charlie",))
114
- db.execute_query("SELECT * FROM employees")
115
- print(db.fetch_all())
116
- 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
117
135
  ```
118
136
  ### MySQL Example
119
- ```pycon
120
- db = SQLPyHelper()
121
- db.execute_query("CREATE TABLE IF NOT EXISTS customers (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100))")
122
- db.execute_query("INSERT INTO customers (name) VALUES (%s)", ("David",))
123
- db.execute_query("SELECT * FROM customers")
124
- print(db.fetch_all())
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')]
125
141
  db.close()
126
142
  ```
127
143
  ### SQL Server Example
128
144
  ```pycon
129
- db = SQLPyHelper()
130
- db.execute_query("CREATE TABLE IF NOT EXISTS orders (id INT PRIMARY KEY, product VARCHAR(100))")
131
- db.execute_query("INSERT INTO orders (id, product) VALUES (?, ?)", (1, "Laptop"))
132
- db.execute_query("SELECT * FROM orders")
133
- print(db.fetch_all())
134
- 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
135
148
  ```
136
149
  ### Oracle Example
137
150
  ```pycon
138
- db = SQLPyHelper()
139
151
  db.execute_query("CREATE TABLE employees (id NUMBER PRIMARY KEY, name VARCHAR2(100))")
140
- db.execute_query("INSERT INTO employees (id, name) VALUES (:1, :2)", (1, "Emily"))
141
- db.execute_query("SELECT * FROM employees")
142
- print(db.fetch_all())
143
- 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)
144
156
  ```
145
157
 
146
158
  ## 📂 Project Structure
@@ -157,6 +169,24 @@ db.close()
157
169
  ├─ README.md
158
170
  └─ requirements.txt
159
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. |
160
190
 
161
191
  ---
162
192
  ## 🌍 Contributing
@@ -0,0 +1,19 @@
1
+ psycopg2
2
+ mysql-connector-python
3
+ pyodbc
4
+ cx_Oracle
5
+ python-dotenv
6
+
7
+ [mysql]
8
+ mysql-connector-python
9
+
10
+ [oracle]
11
+ cx_Oracle
12
+
13
+ [postgres]
14
+ psycopg2
15
+
16
+ [sqlite]
17
+
18
+ [sqlserver]
19
+ pyodbc
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as f:
5
5
 
6
6
  setup(
7
7
  name='SQLPyHelper',
8
- version='0.1.1',
8
+ version='0.1.3',
9
9
  description='A simple SQL database helper package for Python.',
10
10
  long_description=long_description,
11
11
  long_description_content_type="text/markdown",
@@ -19,10 +19,20 @@ setup(
19
19
  'cx_Oracle',
20
20
  'python-dotenv'
21
21
  ],
22
+ extras_require={
23
+ "mysql": ["mysql-connector-python"],
24
+ "postgres": ["psycopg2"],
25
+ "oracle": ["cx_Oracle"],
26
+ "sqlserver": ["pyodbc"],
27
+ "sqlite": []
28
+ },
22
29
  python_requires=">=3.8",
23
30
  classifiers=[
24
31
  "Programming Language :: Python :: 3",
25
- "License :: OSI Approved :: MIT License",
26
- "Operating System :: OS Independent"
32
+ "Development Status :: 5 - Production/Stable",
33
+ "Intended Audience :: Developers",
34
+ "Topic :: Database :: Database Engines/Servers",
35
+ "Operating System :: OS Independent",
36
+ "License :: OSI Approved :: MIT License"
27
37
  ],
28
38
  )
@@ -1,2 +1,2 @@
1
1
  # Match the version in setup.py
2
- __version__ = "0.1.1"
2
+ __version__ = "0.1.3"
@@ -0,0 +1,209 @@
1
+ import csv
2
+ from dotenv import load_dotenv
3
+ import os
4
+
5
+ load_dotenv() # Load environment variables from .env file
6
+
7
+
8
+ def log_query(query):
9
+ """Logs queries for debugging purposes."""
10
+ with open("query_log.txt", "a") as f:
11
+ f.write(query + "\n")
12
+
13
+
14
+ class SQLPyHelper:
15
+ def __init__(self):
16
+ self.db_type = os.getenv("DB_TYPE").lower()
17
+ self.host = os.getenv("DB_HOST")
18
+ self.user = os.getenv("DB_USER")
19
+ self.password = os.getenv("DB_PASSWORD")
20
+ self.database = os.getenv("DB_NAME")
21
+ self.driver = os.getenv("DB_DRIVER")
22
+ self.oracle_sid = os.getenv("ORACLE_SID")
23
+ self.pool = None
24
+
25
+ if self.db_type == "sqlite":
26
+ import sqlite3
27
+ self.connection = sqlite3.connect(self.database)
28
+ elif self.db_type == "postgres":
29
+ import psycopg2
30
+ self.connection = psycopg2.connect(host=self.host, user=self.user,
31
+ password=self.password, dbname=self.database)
32
+ elif self.db_type == "mysql":
33
+ import mysql.connector
34
+ self.connection = mysql.connector.connect(host=self.host, user=self.user,
35
+ password=self.password, database=self.database)
36
+ elif self.db_type == "sqlserver":
37
+ import pyodbc
38
+ self.connection = pyodbc.connect(f"DRIVER={self.driver};SERVER={self.host};DATABASE={self.database};"
39
+ f"UID={self.user};PWD={self.password}")
40
+ elif self.db_type == "oracle":
41
+ import cx_Oracle
42
+ oracle_port = os.getenv("ORACLE_DB_PORT", "1521") # Default to 1521 if not set
43
+ dsn = cx_Oracle.makedsn(self.host, oracle_port, self.oracle_sid)
44
+ self.connection = cx_Oracle.connect(self.user, self.password, dsn)
45
+ else:
46
+ raise ValueError("Unsupported database type")
47
+
48
+ self.cursor = self.connection.cursor()
49
+
50
+ def execute_query(self, query, params=None):
51
+ """Executes a query with optional parameters"""
52
+ try:
53
+ if params:
54
+ self.cursor.execute(query, params)
55
+ else:
56
+ self.cursor.execute(query)
57
+ self.connection.commit()
58
+ except Exception as 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}")
65
+
66
+ def fetch_one(self):
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
73
+
74
+ def fetch_all(self):
75
+ """Fetches all rows from the last executed query"""
76
+ try:
77
+ return self.cursor.fetchall()
78
+ except Exception as e:
79
+ print(f"Error fetching rows: {e}")
80
+ return None
81
+
82
+ def fetch_by_param(self, table_name, column_name, value):
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
90
+
91
+ def close(self):
92
+ """Closes the connection"""
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
99
+
100
+ def create_table(self, table_name, columns):
101
+ """
102
+ Creates a table dynamically using a dictionary format.
103
+ Example:
104
+ columns = {'id': 'INTEGER PRIMARY KEY', 'name': 'TEXT', 'age': 'INTEGER'}
105
+ """
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
113
+
114
+ def insert_bulk(self, table_name, data):
115
+ """
116
+ Inserts multiple rows at once.
117
+ Example:
118
+ data = [{'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}]
119
+ """
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
131
+
132
+ def backup_table(self, table_name, backup_file):
133
+ """
134
+ Exports table data into a CSV file.
135
+ Example:
136
+ backup_table('users', 'users_backup.csv')
137
+ """
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
150
+
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)
181
+
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
187
+
188
+ def get_connection_from_pool(self):
189
+ """Fetches a connection from the pool."""
190
+ return self.pool.get_connection()
191
+
192
+ def return_connection_to_pool(self):
193
+ """Returns a connection back to the pool."""
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")
@@ -0,0 +1,86 @@
1
+ import pytest
2
+ from sqlpyhelper.db_helper import SQLPyHelper
3
+ import os
4
+
5
+
6
+ # Connection test
7
+ @pytest.fixture
8
+ def db():
9
+ """Fixture to initialize and return a database helper instance based on DB_TYPE."""
10
+ db_type = os.getenv("DB_TYPE", "mysql") # Default to MySQL if not set
11
+ os.environ["DB_TYPE"] = db_type # Ensure correct DB type is used
12
+ db_instance = SQLPyHelper()
13
+ yield db_instance
14
+ db_instance.close() # Cleanup after tests
15
+
16
+
17
+ @pytest.mark.skipif(os.getenv("DB_TYPE") != "mysql", reason="Skipping non-MySQL tests")
18
+ def test_connection(db):
19
+ """Ensure MySQL connects successfully."""
20
+ assert db.connection is not None, "MySQL connection failed!"
21
+
22
+
23
+ @pytest.mark.skipif(os.getenv("DB_TYPE") != "mysql", reason="Skipping non-MySQL tests")
24
+ def test_fetch_all(db):
25
+ """Ensure fetch_all retrieves multiple rows in MySQL."""
26
+ db.execute_query("INSERT INTO customers (name) VALUES ('Sade'), ('Rita')")
27
+ db.execute_query("SELECT * FROM customers")
28
+ result = db.fetch_all()
29
+ assert len(result) >= 2, "fetch_all() failed to return expected results!"
30
+
31
+
32
+ # Query Execution & Fetching
33
+ @pytest.mark.parametrize("db_type,query", [
34
+ ("mysql", "CREATE TABLE test_user_tbl (id INT PRIMARY KEY, name VARCHAR(100))"),
35
+ # ("postgres", "CREATE TABLE test_user_tbl (id SERIAL PRIMARY KEY, name TEXT)"),
36
+ # ("sqlserver", "CREATE TABLE test_user_tbl (id INT PRIMARY KEY, name NVARCHAR(100))"),
37
+ # ("oracle", "CREATE TABLE test_user_tbl (id NUMBER PRIMARY KEY, name VARCHAR2(100))")
38
+ ])
39
+ def test_query_execution(db_type, query):
40
+ """Test table creation syntax across database variants."""
41
+ os.environ["DB_TYPE"] = db_type
42
+ db = SQLPyHelper()
43
+ db.execute_query(query)
44
+ assert True # If no errors, test passes
45
+ db.close()
46
+
47
+
48
+ # Parameterized Query Tests
49
+ # @pytest.mark.parametrize("db_type", ["mysql", "postgres", "sqlserver", "oracle"])
50
+ @pytest.mark.parametrize("db_type", ["mysql"])
51
+ def test_fetch_by_param(db_type):
52
+ """Test parameterized queries for different databases."""
53
+ os.environ["DB_TYPE"] = db_type
54
+ db = SQLPyHelper()
55
+
56
+ result = db.fetch_by_param("customers", "name", "David")
57
+ assert len(result) >= 1, f"Failed to fetch record for {db_type}"
58
+ db.close()
59
+
60
+
61
+ # Connection Pooling Validation
62
+ # @pytest.mark.parametrize("db_type", ["mysql", "postgres", "sqlserver", "oracle"])
63
+ @pytest.mark.parametrize("db_type", ["mysql"])
64
+ def test_connection_pooling(db_type):
65
+ """Test pooling setup for different databases."""
66
+ os.environ["DB_TYPE"] = db_type
67
+ db = SQLPyHelper()
68
+ db.setup_connection_pool()
69
+ conn = db.get_connection_from_pool()
70
+ assert conn is not None, f"Pooling failed for {db_type}"
71
+ db.return_connection_to_pool()
72
+ db.close()
73
+
74
+
75
+ # Transaction Management
76
+ def test_transaction_rollback(db):
77
+ """Verify rollback restores previous state."""
78
+ db.begin_transaction()
79
+ db.execute_query("INSERT INTO customers (name) VALUES ('Eve')")
80
+ db.rollback_transaction()
81
+ result = db.fetch_by_param("customers", "name", "Eve")
82
+ assert len(result) == 0, "Rollback did not revert changes!"
83
+
84
+
85
+ # pytest test_sqlpyhelper.py
86
+
@@ -1,159 +0,0 @@
1
- # 📌 SQLPyHelper
2
-
3
- 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.
4
-
5
- ## 📖 Table of Contents
6
- - [🚀 Features](#-features)
7
- - [📦 Installation](#-installation)
8
- - [⚙️ Setup Using `.env`](#️-setup-using-env)
9
- - [🛠 Usage Examples](#-usage-examples)
10
- - [SQLite Example](#sqlite-example)
11
- - [PostgreSQL Example](#postgresql-example)
12
- - [MySQL Example](#mysql-example)
13
- - [SQL Server Example](#sql-server-example)
14
- - [Oracle Example](#oracle-example)
15
- - [📂 Project Structure](#-project-structure)
16
- - [🌍 Contributing](#-contributing)
17
- - [☕ Support the Project](#-support-the-project)
18
-
19
- ---
20
-
21
- ## 🚀 Features
22
- - **Unified Interface** for multiple databases
23
- - **Connection pooling support** for PostgreSQL
24
- - **Bulk insertion & dynamic table creation**
25
- - **Automated logging & query execution**
26
- - **CSV export & backup functionality**
27
-
28
- ---
29
- ## 📦 Installation
30
- ```sh
31
- pip install sqlpyhelper
32
- ```
33
- Or, if working from source:
34
- ```sh
35
- git clone https://github.com/adebayopeter/sqlpyhelper.git
36
- cd sqlpyhelper
37
- pip install -r requirements.txt
38
- ```
39
-
40
- ---
41
-
42
- ## ⚙️ Setup Using `.env`
43
- Create a `.env` file in your project root to manage database configurations securely by renaming `.env_example`.
44
-
45
- ```sh
46
- # .env_example (Rename to .env)
47
- DB_TYPE=postgres
48
- DB_HOST=localhost
49
- DB_USER=your_user
50
- DB_PASSWORD=your_secure_password
51
- DB_NAME=test_db
52
- DB_PORT=5432
53
- DB_DRIVER={ODBC Driver 17 for SQL Server}
54
- ORACLE_SID=XE
55
- ORACLE_PORT=1521
56
- ```
57
- ### Loading `.env` in Code
58
- ```pycon
59
- from dotenv import load_dotenv
60
- import os
61
-
62
- load_dotenv()
63
- db_type = os.getenv("DB_TYPE")
64
- host = os.getenv("DB_HOST")
65
- user = os.getenv("DB_USER")
66
- password = os.getenv("DB_PASSWORD")
67
- database = os.getenv("DB_NAME")
68
- ```
69
- ---
70
- ## 🛠 Usage Examples
71
- ### SQLite Example
72
- ```pycon
73
- from sqlpyhelper.db_helper import SQLPyHelper
74
-
75
- db = SQLPyHelper()
76
- db.execute_query("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
77
- db.execute_query("INSERT INTO users (name) VALUES (?)", ("Alice",))
78
- db.execute_query("SELECT * FROM users")
79
- print(db.fetch_all())
80
- db.close()
81
- ```
82
- ### PostgreSQL Example
83
- ```pycon
84
- db = SQLPyHelper()
85
- db.execute_query("CREATE TABLE IF NOT EXISTS employees (id SERIAL PRIMARY KEY, name VARCHAR(100))")
86
- db.execute_query("INSERT INTO employees (name) VALUES (%s)", ("Charlie",))
87
- db.execute_query("SELECT * FROM employees")
88
- print(db.fetch_all())
89
- db.close()
90
- ```
91
- ### MySQL Example
92
- ```pycon
93
- db = SQLPyHelper()
94
- db.execute_query("CREATE TABLE IF NOT EXISTS customers (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100))")
95
- db.execute_query("INSERT INTO customers (name) VALUES (%s)", ("David",))
96
- db.execute_query("SELECT * FROM customers")
97
- print(db.fetch_all())
98
- db.close()
99
- ```
100
- ### SQL Server Example
101
- ```pycon
102
- db = SQLPyHelper()
103
- db.execute_query("CREATE TABLE IF NOT EXISTS orders (id INT PRIMARY KEY, product VARCHAR(100))")
104
- db.execute_query("INSERT INTO orders (id, product) VALUES (?, ?)", (1, "Laptop"))
105
- db.execute_query("SELECT * FROM orders")
106
- print(db.fetch_all())
107
- db.close()
108
- ```
109
- ### Oracle Example
110
- ```pycon
111
- db = SQLPyHelper()
112
- db.execute_query("CREATE TABLE employees (id NUMBER PRIMARY KEY, name VARCHAR2(100))")
113
- db.execute_query("INSERT INTO employees (id, name) VALUES (:1, :2)", (1, "Emily"))
114
- db.execute_query("SELECT * FROM employees")
115
- print(db.fetch_all())
116
- db.close()
117
- ```
118
-
119
- ## 📂 Project Structure
120
- ```
121
- 📦 SQLPyHelper/
122
- ├─ sqlpyhelper/
123
- │  ├─ __init__.py
124
- │  └─ db_helper.py
125
- ├─ tests/
126
- │  └─ test_sqlpyhelper.py
127
- ├─ .env_example
128
- ├─ .gitignore
129
- ├─ setup.py
130
- ├─ README.md
131
- └─ requirements.txt
132
- ```
133
-
134
- ---
135
- ## 🌍 Contributing
136
- We welcome contributions from the **open-source community**! Follow these steps to contribute:
137
-
138
- 1. Fork the repo: [SQLPyHelper GitHub Repository](https://github.com/adebayopeter/sqlpyhelper)
139
- 2. Clone your fork:
140
- ```sh
141
- git clone https://github.com/adebayopeter/sqlpyhelper.git
142
- ```
143
- 3. Create a new branch:
144
- ```sh
145
- git checkout -b feature-new-functionality
146
- ```
147
- 4. Make changes, commit, and push:
148
- ```sh
149
- git commit -m "Added new feature"
150
- git push origin feature-new-functionality
151
- ```
152
- 5. Submit a Pull Request!
153
-
154
- ---
155
- ## ☕ Support the Project
156
-
157
- If you find SQLPyHelper useful, consider buying me a coffee to support continued development!
158
- Donate Here: [PayPal](https://paypal.me/adebayopeter?country.x=GB&locale.x=en_GB)
159
- ---
@@ -1,5 +0,0 @@
1
- psycopg2
2
- mysql-connector-python
3
- pyodbc
4
- cx_Oracle
5
- python-dotenv
@@ -1,128 +0,0 @@
1
- import sqlite3
2
- import psycopg2
3
- import mysql.connector
4
- import pyodbc
5
- import cx_Oracle
6
- import csv
7
- from psycopg2 import pool
8
- from dotenv import load_dotenv
9
- import os
10
-
11
- load_dotenv() # Load environment variables from .env file
12
-
13
-
14
- class SQLPyHelper:
15
- def __init__(self):
16
- self.db_type = os.getenv("DB_TYPE").lower()
17
- self.host = os.getenv("DB_HOST")
18
- self.user = os.getenv("DB_USER")
19
- self.password = os.getenv("DB_PASSWORD")
20
- self.database = os.getenv("DB_NAME")
21
- self.driver = os.getenv("DB_DRIVER")
22
- self.oracle_sid = os.getenv("ORACLE_SID")
23
-
24
- if self.db_type == "sqlite":
25
- self.connection = sqlite3.connect(self.database)
26
- elif self.db_type == "postgres":
27
- self.connection = psycopg2.connect(host=self.host, user=self.user,
28
- password=self.password, dbname=self.database)
29
- elif self.db_type == "mysql":
30
- self.connection = mysql.connector.connect(host=self.host, user=self.user,
31
- password=self.password, database=self.database)
32
- elif self.db_type == "sqlserver":
33
- self.connection = pyodbc.connect(f"DRIVER={self.driver};SERVER={self.host};DATABASE={self.database};"
34
- f"UID={self.user};PWD={self.password}")
35
- elif self.db_type == "oracle":
36
- oracle_port = os.getenv("ORACLE_DB_PORT", "1521") # Default to 1521 if not set
37
- dsn = cx_Oracle.makedsn(self.host, oracle_port, self.oracle_sid)
38
- self.connection = cx_Oracle.connect(self.user, self.password, dsn)
39
- else:
40
- raise ValueError("Unsupported database type")
41
-
42
- self.cursor = self.connection.cursor()
43
-
44
- def execute_query(self, query, params=None):
45
- """Executes a query with optional parameters"""
46
- try:
47
- if params:
48
- self.cursor.execute(query, params)
49
- else:
50
- self.cursor.execute(query)
51
- self.connection.commit()
52
- except Exception as e:
53
- print(f"Error executing query: {e}")
54
-
55
- def fetch_all(self):
56
- """Fetches all rows from the last executed query"""
57
- return self.cursor.fetchall()
58
-
59
- def close(self):
60
- """Closes the connection"""
61
- self.cursor.close()
62
- self.connection.close()
63
-
64
- def create_table(self, table_name, columns):
65
- """
66
- Creates a table dynamically using a dictionary format.
67
- Example:
68
- columns = {'id': 'INTEGER PRIMARY KEY', 'name': 'TEXT', 'age': 'INTEGER'}
69
- """
70
- column_defs = ", ".join(f"{col} {dtype}" for col, dtype in columns.items())
71
- query = f"CREATE TABLE {table_name} ({column_defs})"
72
- self.execute_query(query)
73
-
74
- def insert_bulk(self, table_name, data):
75
- """
76
- Inserts multiple rows at once.
77
- Example:
78
- data = [{'id': 1, 'name': 'Alice'}, {'id': 2, 'name': 'Bob'}]
79
- """
80
- columns = ", ".join(data[0].keys()) # Extract column names
81
- placeholders = ", ".join(["%s" for _ in data[0].keys()]) # Generate placeholders
82
- query = f"INSERT INTO {table_name} ({columns}) VALUES ({placeholders})"
83
- values = [tuple(row.values()) for row in data] # Convert dictionaries to tuples
84
- self.cursor.executemany(query, values)
85
- self.connection.commit()
86
-
87
- def log_query(self, query):
88
- """Logs queries for debugging purposes."""
89
- with open("query_log.txt", "a") as f:
90
- f.write(query + "\n")
91
-
92
- def backup_table(self, table_name, backup_file):
93
- """
94
- Exports table data into a CSV file.
95
- Example:
96
- backup_table('users', 'users_backup.csv')
97
- """
98
- query = f"SELECT * FROM {table_name}"
99
- self.execute_query(query)
100
- rows = self.fetch_all()
101
-
102
- with open(backup_file, mode="w", newline="") as file:
103
- writer = csv.writer(file)
104
- writer.writerow([desc[0] for desc in self.cursor.description]) # Column headers
105
- writer.writerows(rows)
106
-
107
- def setup_postgres_pool(self, min_conn=1, max_conn=5):
108
- """
109
- Creates a connection pool for PostgreSQL.
110
- Example:
111
- setup_postgres_pool(min_conn=2, max_conn=10)
112
- """
113
- self.pool = pool.SimpleConnectionPool(min_conn, max_conn,
114
- host=self.host,
115
- user=self.user,
116
- password=self.password,
117
- dbname=self.database)
118
-
119
- def get_connection_from_pool(self):
120
- """Fetches a connection from the pool."""
121
- return self.pool.getconn()
122
-
123
- def return_connection_to_pool(self, conn):
124
- """Returns a connection back to the pool."""
125
- self.pool.putconn(conn)
126
-
127
-
128
-
@@ -1,71 +0,0 @@
1
- from sqlpyhelper.db_helper import SQLPyHelper
2
-
3
-
4
- # SQLite Test
5
- def test_sqlite():
6
- print("Testing SQLite...")
7
- db = SQLPyHelper()
8
- db.execute_query("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)")
9
- db.execute_query("INSERT INTO users (name) VALUES (?)", ("Alice",))
10
- db.execute_query("INSERT INTO users (name) VALUES (?)", ("Bob",))
11
- db.execute_query("SELECT * FROM users")
12
- results = db.fetch_all()
13
- print("Results:", results)
14
- db.close()
15
-
16
-
17
- # PostgreSQL Test (Ensure you have PostgreSQL running locally)
18
- def test_postgres():
19
- print("Testing PostgreSQL...")
20
- db = SQLPyHelper()
21
- db.execute_query("CREATE TABLE IF NOT EXISTS employees (id SERIAL PRIMARY KEY, name VARCHAR(100))")
22
- db.execute_query("INSERT INTO employees (name) VALUES (%s)", ("Charlie",))
23
- db.execute_query("SELECT * FROM employees")
24
- results = db.fetch_all()
25
- print("Results:", results)
26
- db.close()
27
-
28
-
29
- # MySQL Test (Ensure MySQL is running locally)
30
- def test_mysql():
31
- print("Testing MySQL...")
32
- db = SQLPyHelper()
33
- db.execute_query("CREATE TABLE IF NOT EXISTS customers (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100))")
34
- db.execute_query("INSERT INTO customers (name) VALUES (%s)", ("Joe",))
35
- db.execute_query("SELECT * FROM customers")
36
- results = db.fetch_all()
37
- print("Results:", results)
38
- db.close()
39
-
40
-
41
- # SQL Server Test (Requires ODBC Driver for SQL Server)
42
- def test_sqlserver():
43
- print("Testing SQL Server...")
44
- db = SQLPyHelper()
45
- db.execute_query("CREATE TABLE IF NOT EXISTS orders (id INT PRIMARY KEY, product VARCHAR(100))")
46
- db.execute_query("INSERT INTO orders (id, product) VALUES (?, ?)", (1, "Laptop"))
47
- db.execute_query("SELECT * FROM orders")
48
- results = db.fetch_all()
49
- print("Results:", results)
50
- db.close()
51
-
52
-
53
- # Oracle Test (Ensure Oracle is installed & running)
54
- def test_oracle():
55
- print("Testing Oracle...")
56
- db = SQLPyHelper()
57
- db.execute_query("CREATE TABLE employees (id NUMBER PRIMARY KEY, name VARCHAR2(100))")
58
- db.execute_query("INSERT INTO employees (id, name) VALUES (:1, :2)", (1, "Emily"))
59
- db.execute_query("SELECT * FROM employees")
60
- results = db.fetch_all()
61
- print("Results:", results)
62
- db.close()
63
-
64
-
65
- # Run Tests
66
- if __name__ == "__main__":
67
- # test_sqlite()
68
- # test_postgres()
69
- test_mysql()
70
- # test_sqlserver()
71
- # test_oracle()
File without changes
File without changes