SQLPyHelper 0.1.4__tar.gz → 0.1.6__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.4 → sqlpyhelper-0.1.6}/PKG-INFO +30 -7
- {sqlpyhelper-0.1.4 → sqlpyhelper-0.1.6}/README.md +26 -4
- {sqlpyhelper-0.1.4 → sqlpyhelper-0.1.6}/SQLPyHelper.egg-info/PKG-INFO +30 -7
- {sqlpyhelper-0.1.4 → sqlpyhelper-0.1.6}/SQLPyHelper.egg-info/SOURCES.txt +2 -1
- {sqlpyhelper-0.1.4 → sqlpyhelper-0.1.6}/SQLPyHelper.egg-info/requires.txt +2 -2
- sqlpyhelper-0.1.6/pyproject.toml +6 -0
- sqlpyhelper-0.1.6/setup.cfg +21 -0
- {sqlpyhelper-0.1.4 → sqlpyhelper-0.1.6}/setup.py +4 -3
- {sqlpyhelper-0.1.4 → sqlpyhelper-0.1.6}/sqlpyhelper/__init__.py +4 -4
- {sqlpyhelper-0.1.4 → sqlpyhelper-0.1.6}/sqlpyhelper/automation_utils.py +26 -15
- sqlpyhelper-0.1.6/sqlpyhelper/cli.py +199 -0
- {sqlpyhelper-0.1.4 → sqlpyhelper-0.1.6}/sqlpyhelper/db_helper.py +164 -65
- sqlpyhelper-0.1.6/test/test_sqlpyhelper.py +558 -0
- sqlpyhelper-0.1.4/setup.cfg +0 -4
- sqlpyhelper-0.1.4/sqlpyhelper/cli.py +0 -146
- sqlpyhelper-0.1.4/test/test_automation.py +0 -15
- sqlpyhelper-0.1.4/test/test_sqlpyhelper.py +0 -86
- {sqlpyhelper-0.1.4 → sqlpyhelper-0.1.6}/LICENSE +0 -0
- {sqlpyhelper-0.1.4 → sqlpyhelper-0.1.6}/SQLPyHelper.egg-info/dependency_links.txt +0 -0
- {sqlpyhelper-0.1.4 → sqlpyhelper-0.1.6}/SQLPyHelper.egg-info/entry_points.txt +0 -0
- {sqlpyhelper-0.1.4 → sqlpyhelper-0.1.6}/SQLPyHelper.egg-info/top_level.txt +0 -0
- {sqlpyhelper-0.1.4 → sqlpyhelper-0.1.6}/sqlpyhelper/py.typed +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: SQLPyHelper
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: A simple SQL database helper package for Python.
|
|
5
5
|
Home-page: https://github.com/adebayopeter/sqlpyhelper
|
|
6
6
|
Author: Adebayo Olaonipekun
|
|
7
7
|
Author-email: pekunmi@live.com
|
|
8
|
+
Project-URL: Documentation, https://sqlpyhelper.readthedocs.io/en/latest/
|
|
8
9
|
Project-URL: Source, https://github.com/adebayopeter/sqlpyhelper
|
|
9
10
|
Project-URL: Bug Tracker, https://github.com/adebayopeter/sqlpyhelper/issues
|
|
10
11
|
Project-URL: Changelog, https://github.com/adebayopeter/sqlpyhelper/blob/main/CHANGELOG.md
|
|
@@ -32,12 +33,12 @@ Requires-Dist: mysql-connector-python; extra == "mysql"
|
|
|
32
33
|
Provides-Extra: sqlserver
|
|
33
34
|
Requires-Dist: pyodbc; extra == "sqlserver"
|
|
34
35
|
Provides-Extra: oracle
|
|
35
|
-
Requires-Dist:
|
|
36
|
+
Requires-Dist: oracledb; extra == "oracle"
|
|
36
37
|
Provides-Extra: all
|
|
37
38
|
Requires-Dist: psycopg2; extra == "all"
|
|
38
39
|
Requires-Dist: mysql-connector-python; extra == "all"
|
|
39
40
|
Requires-Dist: pyodbc; extra == "all"
|
|
40
|
-
Requires-Dist:
|
|
41
|
+
Requires-Dist: oracledb; extra == "all"
|
|
41
42
|
Dynamic: author
|
|
42
43
|
Dynamic: author-email
|
|
43
44
|
Dynamic: classifier
|
|
@@ -59,10 +60,19 @@ Dynamic: summary
|
|
|
59
60
|
[](https://pypi.org/project/sqlpyhelper/)
|
|
60
61
|
[](https://github.com/adebayopeter/sqlpyhelper/blob/main/LICENSE)
|
|
61
62
|
[](https://github.com/adebayopeter/sqlpyhelper)
|
|
63
|
+
[](https://sqlpyhelper.readthedocs.io/en/latest/)
|
|
62
64
|
|
|
63
|
-
|
|
65
|
+
SQLPyHelper is a lightweight Python library that gives you a single, consistent API across **SQLite, PostgreSQL, MySQL, SQL Server, and Oracle** — without the overhead of an ORM.
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
If you need to run queries, manage transactions, pool connections, or back up tables across multiple database types without learning SQLAlchemy's abstraction layer or wiring up five different drivers manually, SQLPyHelper handles that boilerplate for you.
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
# Works identically across all five supported databases
|
|
71
|
+
with SQLPyHelper(db_type="postgres", host="localhost", user="user",
|
|
72
|
+
password="pass", database="mydb") as db:
|
|
73
|
+
db.execute_query("INSERT INTO orders (item) VALUES (%s)", ("Laptop",))
|
|
74
|
+
results = db.fetch_all()
|
|
75
|
+
```
|
|
66
76
|
|
|
67
77
|
## 📖 Table of Contents
|
|
68
78
|
- [🚀 Features](#-features)
|
|
@@ -81,7 +91,7 @@ A Python library for simplified database interactions across **SQLite, PostgreSQ
|
|
|
81
91
|
|
|
82
92
|
---
|
|
83
93
|
|
|
84
|
-
## 🚀 Features in v0.1.
|
|
94
|
+
## 🚀 Features in v0.1.4
|
|
85
95
|
- Unified connection pooling for multiple databases.
|
|
86
96
|
- Automatic reconnection for lost connections.
|
|
87
97
|
- Transaction support (BEGIN, ROLLBACK, COMMIT).
|
|
@@ -92,10 +102,21 @@ A Python library for simplified database interactions across **SQLite, PostgreSQ
|
|
|
92
102
|
|
|
93
103
|
---
|
|
94
104
|
## 📦 Installation
|
|
95
|
-
|
|
105
|
+
|
|
106
|
+
Install the base package (includes SQLite support out of the box):
|
|
96
107
|
```sh
|
|
97
108
|
pip install sqlpyhelper
|
|
98
109
|
```
|
|
110
|
+
|
|
111
|
+
Install with your database driver:
|
|
112
|
+
```sh
|
|
113
|
+
pip install sqlpyhelper[postgres] # PostgreSQL
|
|
114
|
+
pip install sqlpyhelper[mysql] # MySQL
|
|
115
|
+
pip install sqlpyhelper[sqlserver] # SQL Server
|
|
116
|
+
pip install sqlpyhelper[oracle] # Oracle
|
|
117
|
+
pip install sqlpyhelper[all] # All databases
|
|
118
|
+
```
|
|
119
|
+
|
|
99
120
|
📌 Package on PyPI: [SQLPyHelper on PyPI](https://pypi.org/project/SQLPyHelper/)
|
|
100
121
|
|
|
101
122
|
For local development:
|
|
@@ -208,7 +229,9 @@ db.return_connection_to_pool(conn)
|
|
|
208
229
|
| `return_connection_to_pool(conn)` | Returns connection back to pool. |
|
|
209
230
|
| `begin_transaction()` | Begins an **explicit transaction**. |
|
|
210
231
|
| `rollback_transaction()` | Rolls back **uncommitted transactions**. |
|
|
232
|
+
| `commit_transaction()` | Commits the current transaction. |
|
|
211
233
|
| `close()` | Closes the database connection safely. |
|
|
234
|
+
| `__enter__` / `__exit__()` | Use as a context manager — connection closes automatically. |
|
|
212
235
|
|
|
213
236
|
---
|
|
214
237
|
## 🌍 Contributing
|
|
@@ -5,10 +5,19 @@
|
|
|
5
5
|
[](https://pypi.org/project/sqlpyhelper/)
|
|
6
6
|
[](https://github.com/adebayopeter/sqlpyhelper/blob/main/LICENSE)
|
|
7
7
|
[](https://github.com/adebayopeter/sqlpyhelper)
|
|
8
|
+
[](https://sqlpyhelper.readthedocs.io/en/latest/)
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
SQLPyHelper is a lightweight Python library that gives you a single, consistent API across **SQLite, PostgreSQL, MySQL, SQL Server, and Oracle** — without the overhead of an ORM.
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
If you need to run queries, manage transactions, pool connections, or back up tables across multiple database types without learning SQLAlchemy's abstraction layer or wiring up five different drivers manually, SQLPyHelper handles that boilerplate for you.
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
# Works identically across all five supported databases
|
|
16
|
+
with SQLPyHelper(db_type="postgres", host="localhost", user="user",
|
|
17
|
+
password="pass", database="mydb") as db:
|
|
18
|
+
db.execute_query("INSERT INTO orders (item) VALUES (%s)", ("Laptop",))
|
|
19
|
+
results = db.fetch_all()
|
|
20
|
+
```
|
|
12
21
|
|
|
13
22
|
## 📖 Table of Contents
|
|
14
23
|
- [🚀 Features](#-features)
|
|
@@ -27,7 +36,7 @@ A Python library for simplified database interactions across **SQLite, PostgreSQ
|
|
|
27
36
|
|
|
28
37
|
---
|
|
29
38
|
|
|
30
|
-
## 🚀 Features in v0.1.
|
|
39
|
+
## 🚀 Features in v0.1.4
|
|
31
40
|
- Unified connection pooling for multiple databases.
|
|
32
41
|
- Automatic reconnection for lost connections.
|
|
33
42
|
- Transaction support (BEGIN, ROLLBACK, COMMIT).
|
|
@@ -38,10 +47,21 @@ A Python library for simplified database interactions across **SQLite, PostgreSQ
|
|
|
38
47
|
|
|
39
48
|
---
|
|
40
49
|
## 📦 Installation
|
|
41
|
-
|
|
50
|
+
|
|
51
|
+
Install the base package (includes SQLite support out of the box):
|
|
42
52
|
```sh
|
|
43
53
|
pip install sqlpyhelper
|
|
44
54
|
```
|
|
55
|
+
|
|
56
|
+
Install with your database driver:
|
|
57
|
+
```sh
|
|
58
|
+
pip install sqlpyhelper[postgres] # PostgreSQL
|
|
59
|
+
pip install sqlpyhelper[mysql] # MySQL
|
|
60
|
+
pip install sqlpyhelper[sqlserver] # SQL Server
|
|
61
|
+
pip install sqlpyhelper[oracle] # Oracle
|
|
62
|
+
pip install sqlpyhelper[all] # All databases
|
|
63
|
+
```
|
|
64
|
+
|
|
45
65
|
📌 Package on PyPI: [SQLPyHelper on PyPI](https://pypi.org/project/SQLPyHelper/)
|
|
46
66
|
|
|
47
67
|
For local development:
|
|
@@ -154,7 +174,9 @@ db.return_connection_to_pool(conn)
|
|
|
154
174
|
| `return_connection_to_pool(conn)` | Returns connection back to pool. |
|
|
155
175
|
| `begin_transaction()` | Begins an **explicit transaction**. |
|
|
156
176
|
| `rollback_transaction()` | Rolls back **uncommitted transactions**. |
|
|
177
|
+
| `commit_transaction()` | Commits the current transaction. |
|
|
157
178
|
| `close()` | Closes the database connection safely. |
|
|
179
|
+
| `__enter__` / `__exit__()` | Use as a context manager — connection closes automatically. |
|
|
158
180
|
|
|
159
181
|
---
|
|
160
182
|
## 🌍 Contributing
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: SQLPyHelper
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: A simple SQL database helper package for Python.
|
|
5
5
|
Home-page: https://github.com/adebayopeter/sqlpyhelper
|
|
6
6
|
Author: Adebayo Olaonipekun
|
|
7
7
|
Author-email: pekunmi@live.com
|
|
8
|
+
Project-URL: Documentation, https://sqlpyhelper.readthedocs.io/en/latest/
|
|
8
9
|
Project-URL: Source, https://github.com/adebayopeter/sqlpyhelper
|
|
9
10
|
Project-URL: Bug Tracker, https://github.com/adebayopeter/sqlpyhelper/issues
|
|
10
11
|
Project-URL: Changelog, https://github.com/adebayopeter/sqlpyhelper/blob/main/CHANGELOG.md
|
|
@@ -32,12 +33,12 @@ Requires-Dist: mysql-connector-python; extra == "mysql"
|
|
|
32
33
|
Provides-Extra: sqlserver
|
|
33
34
|
Requires-Dist: pyodbc; extra == "sqlserver"
|
|
34
35
|
Provides-Extra: oracle
|
|
35
|
-
Requires-Dist:
|
|
36
|
+
Requires-Dist: oracledb; extra == "oracle"
|
|
36
37
|
Provides-Extra: all
|
|
37
38
|
Requires-Dist: psycopg2; extra == "all"
|
|
38
39
|
Requires-Dist: mysql-connector-python; extra == "all"
|
|
39
40
|
Requires-Dist: pyodbc; extra == "all"
|
|
40
|
-
Requires-Dist:
|
|
41
|
+
Requires-Dist: oracledb; extra == "all"
|
|
41
42
|
Dynamic: author
|
|
42
43
|
Dynamic: author-email
|
|
43
44
|
Dynamic: classifier
|
|
@@ -59,10 +60,19 @@ Dynamic: summary
|
|
|
59
60
|
[](https://pypi.org/project/sqlpyhelper/)
|
|
60
61
|
[](https://github.com/adebayopeter/sqlpyhelper/blob/main/LICENSE)
|
|
61
62
|
[](https://github.com/adebayopeter/sqlpyhelper)
|
|
63
|
+
[](https://sqlpyhelper.readthedocs.io/en/latest/)
|
|
62
64
|
|
|
63
|
-
|
|
65
|
+
SQLPyHelper is a lightweight Python library that gives you a single, consistent API across **SQLite, PostgreSQL, MySQL, SQL Server, and Oracle** — without the overhead of an ORM.
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
If you need to run queries, manage transactions, pool connections, or back up tables across multiple database types without learning SQLAlchemy's abstraction layer or wiring up five different drivers manually, SQLPyHelper handles that boilerplate for you.
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
# Works identically across all five supported databases
|
|
71
|
+
with SQLPyHelper(db_type="postgres", host="localhost", user="user",
|
|
72
|
+
password="pass", database="mydb") as db:
|
|
73
|
+
db.execute_query("INSERT INTO orders (item) VALUES (%s)", ("Laptop",))
|
|
74
|
+
results = db.fetch_all()
|
|
75
|
+
```
|
|
66
76
|
|
|
67
77
|
## 📖 Table of Contents
|
|
68
78
|
- [🚀 Features](#-features)
|
|
@@ -81,7 +91,7 @@ A Python library for simplified database interactions across **SQLite, PostgreSQ
|
|
|
81
91
|
|
|
82
92
|
---
|
|
83
93
|
|
|
84
|
-
## 🚀 Features in v0.1.
|
|
94
|
+
## 🚀 Features in v0.1.4
|
|
85
95
|
- Unified connection pooling for multiple databases.
|
|
86
96
|
- Automatic reconnection for lost connections.
|
|
87
97
|
- Transaction support (BEGIN, ROLLBACK, COMMIT).
|
|
@@ -92,10 +102,21 @@ A Python library for simplified database interactions across **SQLite, PostgreSQ
|
|
|
92
102
|
|
|
93
103
|
---
|
|
94
104
|
## 📦 Installation
|
|
95
|
-
|
|
105
|
+
|
|
106
|
+
Install the base package (includes SQLite support out of the box):
|
|
96
107
|
```sh
|
|
97
108
|
pip install sqlpyhelper
|
|
98
109
|
```
|
|
110
|
+
|
|
111
|
+
Install with your database driver:
|
|
112
|
+
```sh
|
|
113
|
+
pip install sqlpyhelper[postgres] # PostgreSQL
|
|
114
|
+
pip install sqlpyhelper[mysql] # MySQL
|
|
115
|
+
pip install sqlpyhelper[sqlserver] # SQL Server
|
|
116
|
+
pip install sqlpyhelper[oracle] # Oracle
|
|
117
|
+
pip install sqlpyhelper[all] # All databases
|
|
118
|
+
```
|
|
119
|
+
|
|
99
120
|
📌 Package on PyPI: [SQLPyHelper on PyPI](https://pypi.org/project/SQLPyHelper/)
|
|
100
121
|
|
|
101
122
|
For local development:
|
|
@@ -208,7 +229,9 @@ db.return_connection_to_pool(conn)
|
|
|
208
229
|
| `return_connection_to_pool(conn)` | Returns connection back to pool. |
|
|
209
230
|
| `begin_transaction()` | Begins an **explicit transaction**. |
|
|
210
231
|
| `rollback_transaction()` | Rolls back **uncommitted transactions**. |
|
|
232
|
+
| `commit_transaction()` | Commits the current transaction. |
|
|
211
233
|
| `close()` | Closes the database connection safely. |
|
|
234
|
+
| `__enter__` / `__exit__()` | Use as a context manager — connection closes automatically. |
|
|
212
235
|
|
|
213
236
|
---
|
|
214
237
|
## 🌍 Contributing
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
LICENSE
|
|
2
2
|
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.cfg
|
|
3
5
|
setup.py
|
|
4
6
|
SQLPyHelper.egg-info/PKG-INFO
|
|
5
7
|
SQLPyHelper.egg-info/SOURCES.txt
|
|
@@ -12,5 +14,4 @@ sqlpyhelper/automation_utils.py
|
|
|
12
14
|
sqlpyhelper/cli.py
|
|
13
15
|
sqlpyhelper/db_helper.py
|
|
14
16
|
sqlpyhelper/py.typed
|
|
15
|
-
test/test_automation.py
|
|
16
17
|
test/test_sqlpyhelper.py
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[flake8]
|
|
2
|
+
max-line-length = 120
|
|
3
|
+
ignore =
|
|
4
|
+
E203,
|
|
5
|
+
E501,
|
|
6
|
+
W503
|
|
7
|
+
exclude =
|
|
8
|
+
venv,
|
|
9
|
+
.git,
|
|
10
|
+
__pycache__,
|
|
11
|
+
dist,
|
|
12
|
+
build,
|
|
13
|
+
*.egg-info
|
|
14
|
+
|
|
15
|
+
[mypy]
|
|
16
|
+
ignore_missing_imports = True
|
|
17
|
+
|
|
18
|
+
[egg_info]
|
|
19
|
+
tag_build =
|
|
20
|
+
tag_date = 0
|
|
21
|
+
|
|
@@ -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.6',
|
|
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",
|
|
@@ -25,12 +25,12 @@ setup(
|
|
|
25
25
|
"postgres": ["psycopg2"],
|
|
26
26
|
"mysql": ["mysql-connector-python"],
|
|
27
27
|
"sqlserver": ["pyodbc"],
|
|
28
|
-
"oracle": ["
|
|
28
|
+
"oracle": ["oracledb"],
|
|
29
29
|
"all": [
|
|
30
30
|
"psycopg2",
|
|
31
31
|
"mysql-connector-python",
|
|
32
32
|
"pyodbc",
|
|
33
|
-
"
|
|
33
|
+
"oracledb",
|
|
34
34
|
],
|
|
35
35
|
},
|
|
36
36
|
keywords=[
|
|
@@ -38,6 +38,7 @@ setup(
|
|
|
38
38
|
"sqlserver", "oracle", "db", "query", "helper",
|
|
39
39
|
],
|
|
40
40
|
project_urls={
|
|
41
|
+
"Documentation": "https://sqlpyhelper.readthedocs.io/en/latest/",
|
|
41
42
|
"Source": "https://github.com/adebayopeter/sqlpyhelper",
|
|
42
43
|
"Bug Tracker": "https://github.com/adebayopeter/sqlpyhelper/issues",
|
|
43
44
|
"Changelog": "https://github.com/adebayopeter/sqlpyhelper/blob/main/CHANGELOG.md",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Match the version in setup.py
|
|
2
|
-
__version__ = "0.1.
|
|
2
|
+
__version__ = "0.1.6"
|
|
3
3
|
|
|
4
|
-
from sqlpyhelper.db_helper import (
|
|
5
|
-
|
|
4
|
+
from sqlpyhelper.db_helper import ( # noqa: F401
|
|
5
|
+
BackupError,
|
|
6
6
|
ConnectionError,
|
|
7
7
|
QueryError,
|
|
8
|
-
|
|
8
|
+
SQLPyHelperError,
|
|
9
9
|
)
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import pandas as pd
|
|
2
|
-
from sqlpyhelper.db_helper import SQLPyHelper
|
|
3
|
-
import subprocess
|
|
4
|
-
from datetime import datetime
|
|
5
1
|
import os
|
|
6
2
|
import shutil
|
|
3
|
+
import subprocess
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
|
|
6
|
+
import pandas as pd
|
|
7
|
+
|
|
8
|
+
from sqlpyhelper.db_helper import SQLPyHelper
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
class AutomationUtils:
|
|
@@ -43,12 +45,17 @@ class AutomationUtils:
|
|
|
43
45
|
subprocess.run(
|
|
44
46
|
[
|
|
45
47
|
"pg_dump",
|
|
46
|
-
"-h",
|
|
47
|
-
|
|
48
|
-
"-
|
|
48
|
+
"-h",
|
|
49
|
+
host,
|
|
50
|
+
"-p",
|
|
51
|
+
port,
|
|
52
|
+
"-U",
|
|
53
|
+
user,
|
|
49
54
|
db_name,
|
|
50
|
-
"-F",
|
|
51
|
-
"
|
|
55
|
+
"-F",
|
|
56
|
+
"c",
|
|
57
|
+
"-f",
|
|
58
|
+
filepath,
|
|
52
59
|
],
|
|
53
60
|
check=True,
|
|
54
61
|
shell=False,
|
|
@@ -82,7 +89,7 @@ class AutomationUtils:
|
|
|
82
89
|
entity_column (str): Column representing entity ID.
|
|
83
90
|
date_column (str): Column representing timestamp/date.
|
|
84
91
|
"""
|
|
85
|
-
if self.db.db_type ==
|
|
92
|
+
if self.db.db_type == "sqlite":
|
|
86
93
|
month_expr = f"strftime('%Y-%m', {date_column})"
|
|
87
94
|
else:
|
|
88
95
|
month_expr = f"DATE_TRUNC('month', {date_column})"
|
|
@@ -95,7 +102,9 @@ class AutomationUtils:
|
|
|
95
102
|
self.db.execute_query(query)
|
|
96
103
|
return self.db.fetch_all()
|
|
97
104
|
|
|
98
|
-
def aggregate_column(
|
|
105
|
+
def aggregate_column(
|
|
106
|
+
self, table, value_column, group_column=None, time_column=None
|
|
107
|
+
):
|
|
99
108
|
"""
|
|
100
109
|
Computes sum of any value column grouped by entity or month.
|
|
101
110
|
|
|
@@ -105,7 +114,7 @@ class AutomationUtils:
|
|
|
105
114
|
group_column (str, optional): Entity or category to group by.
|
|
106
115
|
time_column (str, optional): Timestamp to extract month grouping.
|
|
107
116
|
"""
|
|
108
|
-
if self.db.db_type ==
|
|
117
|
+
if self.db.db_type == "sqlite":
|
|
109
118
|
month_expr = f"strftime('%Y-%m', {time_column})"
|
|
110
119
|
else:
|
|
111
120
|
month_expr = f"DATE_TRUNC('month', {time_column})"
|
|
@@ -133,11 +142,13 @@ class AutomationUtils:
|
|
|
133
142
|
threshold (int): Number of standard deviations from mean to flag as outlier.
|
|
134
143
|
"""
|
|
135
144
|
query = f"""
|
|
136
|
-
|
|
137
|
-
AS value FROM {table}
|
|
145
|
+
SELECT *, {numeric_column} AS value FROM {table}
|
|
138
146
|
"""
|
|
139
147
|
self.db.execute_query(query)
|
|
140
|
-
data = pd.DataFrame(
|
|
148
|
+
data = pd.DataFrame(
|
|
149
|
+
self.db.fetch_all(),
|
|
150
|
+
columns=[desc[0] for desc in self.db.cursor.description],
|
|
151
|
+
)
|
|
141
152
|
|
|
142
153
|
mean_val = data["value"].mean()
|
|
143
154
|
std_val = data["value"].std()
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from sqlpyhelper.automation_utils import AutomationUtils
|
|
4
|
+
from sqlpyhelper.db_helper import SQLPyHelper
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@click.group()
|
|
8
|
+
def cli():
|
|
9
|
+
"""SQLPyHelper Command Line Interface"""
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@cli.command()
|
|
14
|
+
@click.option("--db_type", help="Type of database (e.g., sqlite, postgres, mysql)")
|
|
15
|
+
@click.option("--host", help="Database host")
|
|
16
|
+
@click.option("--user", help="Username")
|
|
17
|
+
@click.option("--password", help="Password")
|
|
18
|
+
@click.option("--database", help="Database name or file")
|
|
19
|
+
@click.option("--query", required=True, help="SQL query to run")
|
|
20
|
+
def run_query(db_type, host, user, password, database, query):
|
|
21
|
+
"""Run a single SQL query and print results"""
|
|
22
|
+
db = SQLPyHelper(
|
|
23
|
+
db_type=db_type, host=host, user=user, password=password, database=database
|
|
24
|
+
)
|
|
25
|
+
results = db.execute_query(query)
|
|
26
|
+
for row in results:
|
|
27
|
+
click.echo(row)
|
|
28
|
+
db.close()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@cli.command()
|
|
32
|
+
@click.option("--db_type", required=True)
|
|
33
|
+
@click.option("--host")
|
|
34
|
+
@click.option("--user")
|
|
35
|
+
@click.option("--password")
|
|
36
|
+
@click.option("--database", required=True)
|
|
37
|
+
def interactive_shell(db_type, host, user, password, database):
|
|
38
|
+
"""Launch an interactive SQL shell"""
|
|
39
|
+
db = SQLPyHelper(
|
|
40
|
+
db_type=db_type, host=host, user=user, password=password, database=database
|
|
41
|
+
)
|
|
42
|
+
click.echo("Interactive shell started. Type your SQL query or 'exit'")
|
|
43
|
+
while True:
|
|
44
|
+
query = input("sqlpy> ")
|
|
45
|
+
if query.lower() in ("exit", "quit"):
|
|
46
|
+
break
|
|
47
|
+
try:
|
|
48
|
+
db.execute_query(query)
|
|
49
|
+
results = db.fetch_all()
|
|
50
|
+
for row in results:
|
|
51
|
+
click.echo(row)
|
|
52
|
+
except Exception as e:
|
|
53
|
+
click.echo(f"Error: {e}")
|
|
54
|
+
db.close()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@cli.command()
|
|
58
|
+
@click.option("--target", default="local", help="Backup destination")
|
|
59
|
+
@click.option("--tag", default="autobackup", help="Tag for backup file naming")
|
|
60
|
+
@click.option("--db-type")
|
|
61
|
+
@click.option("--host")
|
|
62
|
+
@click.option("--user")
|
|
63
|
+
@click.option("--password")
|
|
64
|
+
@click.option("--database")
|
|
65
|
+
@click.option("--port")
|
|
66
|
+
def backup(target, tag, db_type, host, user, password, database, port):
|
|
67
|
+
"""Create a timestamped backup of the connected database."""
|
|
68
|
+
utils = AutomationUtils(
|
|
69
|
+
db_type=db_type,
|
|
70
|
+
host=host,
|
|
71
|
+
user=user,
|
|
72
|
+
password=password,
|
|
73
|
+
database=database,
|
|
74
|
+
port=port,
|
|
75
|
+
)
|
|
76
|
+
utils.backup_database(target=target, tag=tag)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@cli.command()
|
|
80
|
+
@click.option("--file", required=True, help="Path to CSV file")
|
|
81
|
+
@click.option("--table", required=True, help="Destination table")
|
|
82
|
+
@click.option(
|
|
83
|
+
"--if-exists",
|
|
84
|
+
default="append",
|
|
85
|
+
type=click.Choice(["append", "replace"]),
|
|
86
|
+
help="What to do if table exists",
|
|
87
|
+
)
|
|
88
|
+
@click.option("--db-type")
|
|
89
|
+
@click.option("--host")
|
|
90
|
+
@click.option("--user")
|
|
91
|
+
@click.option("--password")
|
|
92
|
+
@click.option("--database")
|
|
93
|
+
@click.option("--port")
|
|
94
|
+
def load_data(file, table, if_exists, db_type, host, user, password, database, port):
|
|
95
|
+
"""Load data from CSV into database table."""
|
|
96
|
+
utils = AutomationUtils(
|
|
97
|
+
db_type=db_type,
|
|
98
|
+
host=host,
|
|
99
|
+
user=user,
|
|
100
|
+
password=password,
|
|
101
|
+
database=database,
|
|
102
|
+
port=port,
|
|
103
|
+
)
|
|
104
|
+
utils.load_data_from_csv(file, table, if_exists=if_exists)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@cli.command()
|
|
108
|
+
@click.option("--table", required=True)
|
|
109
|
+
@click.option("--entity-column", required=True)
|
|
110
|
+
@click.option("--date-column", required=True)
|
|
111
|
+
@click.option("--db-type")
|
|
112
|
+
@click.option("--host")
|
|
113
|
+
@click.option("--user")
|
|
114
|
+
@click.option("--password")
|
|
115
|
+
@click.option("--database")
|
|
116
|
+
@click.option("--port")
|
|
117
|
+
def detect_missing_periods(
|
|
118
|
+
table, entity_column, date_column, db_type, host, user, password, database, port
|
|
119
|
+
):
|
|
120
|
+
"""Flag entities with fewer than 12 months of activity."""
|
|
121
|
+
utils = AutomationUtils(
|
|
122
|
+
db_type=db_type,
|
|
123
|
+
host=host,
|
|
124
|
+
user=user,
|
|
125
|
+
password=password,
|
|
126
|
+
database=database,
|
|
127
|
+
port=port,
|
|
128
|
+
)
|
|
129
|
+
results = utils.detect_missing_periods(table, entity_column, date_column)
|
|
130
|
+
for row in results:
|
|
131
|
+
click.echo(row)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@cli.command()
|
|
135
|
+
@click.option("--table", required=True)
|
|
136
|
+
@click.option("--value-column", required=True)
|
|
137
|
+
@click.option("--group-column")
|
|
138
|
+
@click.option("--time-column")
|
|
139
|
+
@click.option("--db-type")
|
|
140
|
+
@click.option("--host")
|
|
141
|
+
@click.option("--user")
|
|
142
|
+
@click.option("--password")
|
|
143
|
+
@click.option("--database")
|
|
144
|
+
@click.option("--port")
|
|
145
|
+
def aggregate(
|
|
146
|
+
table,
|
|
147
|
+
value_column,
|
|
148
|
+
group_column,
|
|
149
|
+
time_column,
|
|
150
|
+
db_type,
|
|
151
|
+
host,
|
|
152
|
+
user,
|
|
153
|
+
password,
|
|
154
|
+
database,
|
|
155
|
+
port,
|
|
156
|
+
):
|
|
157
|
+
"""Aggregate numeric column optionally grouped by entity and time."""
|
|
158
|
+
utils = AutomationUtils(
|
|
159
|
+
db_type=db_type,
|
|
160
|
+
host=host,
|
|
161
|
+
user=user,
|
|
162
|
+
password=password,
|
|
163
|
+
database=database,
|
|
164
|
+
port=port,
|
|
165
|
+
)
|
|
166
|
+
results = utils.aggregate_column(table, value_column, group_column, time_column)
|
|
167
|
+
for row in results:
|
|
168
|
+
click.echo(row)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@cli.command()
|
|
172
|
+
@click.option("--table", required=True)
|
|
173
|
+
@click.option("--numeric-column", required=True)
|
|
174
|
+
@click.option("--threshold", default=2, type=int)
|
|
175
|
+
@click.option("--db-type")
|
|
176
|
+
@click.option("--host")
|
|
177
|
+
@click.option("--user")
|
|
178
|
+
@click.option("--password")
|
|
179
|
+
@click.option("--database")
|
|
180
|
+
@click.option("--port")
|
|
181
|
+
def detect_outliers(
|
|
182
|
+
table, numeric_column, threshold, db_type, host, user, password, database, port
|
|
183
|
+
):
|
|
184
|
+
"""Flag rows where values deviate statistically from average."""
|
|
185
|
+
utils = AutomationUtils(
|
|
186
|
+
db_type=db_type,
|
|
187
|
+
host=host,
|
|
188
|
+
user=user,
|
|
189
|
+
password=password,
|
|
190
|
+
database=database,
|
|
191
|
+
port=port,
|
|
192
|
+
)
|
|
193
|
+
results = utils.detect_outliers(table, numeric_column, threshold)
|
|
194
|
+
for row in results:
|
|
195
|
+
click.echo(row)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
if __name__ == "__main__":
|
|
199
|
+
cli()
|