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.
- {sqlpyhelper-0.1.1 → sqlpyhelper-0.1.3}/PKG-INFO +72 -42
- sqlpyhelper-0.1.3/README.md +176 -0
- {sqlpyhelper-0.1.1 → sqlpyhelper-0.1.3}/SQLPyHelper.egg-info/PKG-INFO +72 -42
- sqlpyhelper-0.1.3/SQLPyHelper.egg-info/requires.txt +19 -0
- {sqlpyhelper-0.1.1 → sqlpyhelper-0.1.3}/setup.py +13 -3
- {sqlpyhelper-0.1.1 → sqlpyhelper-0.1.3}/sqlpyhelper/__init__.py +1 -1
- sqlpyhelper-0.1.3/sqlpyhelper/db_helper.py +209 -0
- sqlpyhelper-0.1.3/test/test_sqlpyhelper.py +86 -0
- sqlpyhelper-0.1.1/README.md +0 -159
- sqlpyhelper-0.1.1/SQLPyHelper.egg-info/requires.txt +0 -5
- sqlpyhelper-0.1.1/sqlpyhelper/db_helper.py +0 -128
- sqlpyhelper-0.1.1/test/test_sqlpyhelper.py +0 -71
- {sqlpyhelper-0.1.1 → sqlpyhelper-0.1.3}/LICENSE +0 -0
- {sqlpyhelper-0.1.1 → sqlpyhelper-0.1.3}/SQLPyHelper.egg-info/SOURCES.txt +0 -0
- {sqlpyhelper-0.1.1 → sqlpyhelper-0.1.3}/SQLPyHelper.egg-info/dependency_links.txt +0 -0
- {sqlpyhelper-0.1.1 → sqlpyhelper-0.1.3}/SQLPyHelper.egg-info/top_level.txt +0 -0
- {sqlpyhelper-0.1.1 → sqlpyhelper-0.1.3}/setup.cfg +0 -0
|
@@ -1,12 +1,15 @@
|
|
|
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
|
|
7
7
|
Classifier: Programming Language :: Python :: 3
|
|
8
|
-
Classifier:
|
|
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**.
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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
|
-
###
|
|
116
|
+
### Initialize SQLPyHelper
|
|
99
117
|
```pycon
|
|
100
118
|
from sqlpyhelper.db_helper import SQLPyHelper
|
|
101
|
-
|
|
102
|
-
|
|
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.
|
|
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
|
|
112
|
-
db.execute_query("
|
|
113
|
-
db.
|
|
114
|
-
db.execute_query("
|
|
115
|
-
|
|
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
|
|
121
|
-
db.execute_query("
|
|
122
|
-
db.
|
|
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
|
|
130
|
-
db.
|
|
131
|
-
db.
|
|
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, "
|
|
141
|
-
db.
|
|
142
|
-
|
|
143
|
-
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)
|
|
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.
|
|
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:
|
|
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**.
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
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
|
-
###
|
|
116
|
+
### Initialize SQLPyHelper
|
|
99
117
|
```pycon
|
|
100
118
|
from sqlpyhelper.db_helper import SQLPyHelper
|
|
101
|
-
|
|
102
|
-
|
|
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.
|
|
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
|
|
112
|
-
db.execute_query("
|
|
113
|
-
db.
|
|
114
|
-
db.execute_query("
|
|
115
|
-
|
|
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
|
|
121
|
-
db.execute_query("
|
|
122
|
-
db.
|
|
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
|
|
130
|
-
db.
|
|
131
|
-
db.
|
|
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, "
|
|
141
|
-
db.
|
|
142
|
-
|
|
143
|
-
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)
|
|
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
|
|
@@ -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.
|
|
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
|
-
"
|
|
26
|
-
"
|
|
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.
|
|
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
|
+
|
sqlpyhelper-0.1.1/README.md
DELETED
|
@@ -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,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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|