python-databases 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- python_databases/__init__.py +0 -12
- python_databases/{elastic_search_infrastructure → elasticsearch_infrastructure}/__init__.py +1 -1
- python_databases/{elastic_search_infrastructure/elastic_search.py → elasticsearch_infrastructure/elasticsearch.py} +8 -7
- python_databases/postgresql_infrastructure/__init__.py +3 -0
- python_databases/postgresql_infrastructure/postgresql.py +83 -0
- python_databases-0.1.2.dist-info/METADATA +75 -0
- python_databases-0.1.2.dist-info/RECORD +10 -0
- python_databases-0.1.0.dist-info/METADATA +0 -31
- python_databases-0.1.0.dist-info/RECORD +0 -8
- {python_databases-0.1.0.dist-info → python_databases-0.1.2.dist-info}/WHEEL +0 -0
- {python_databases-0.1.0.dist-info → python_databases-0.1.2.dist-info}/licenses/LICENSE +0 -0
- {python_databases-0.1.0.dist-info → python_databases-0.1.2.dist-info}/top_level.txt +0 -0
python_databases/__init__.py
CHANGED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
from dotenv import load_dotenv
|
|
2
|
-
|
|
3
|
-
from python_databases.elastic_search_infrastructure.elastic_search import (
|
|
4
|
-
UrlProtocol,
|
|
5
|
-
ElasticSearch,
|
|
6
|
-
ElasticSearchOnPrem,
|
|
7
|
-
ElasticSearchCloud
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
load_dotenv()
|
|
11
|
-
|
|
12
|
-
__all__ = ['UrlProtocol', 'ElasticSearch', 'ElasticSearchOnPrem', 'ElasticSearchCloud']
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import datetime
|
|
2
1
|
import logging
|
|
3
2
|
import time
|
|
4
3
|
from abc import ABC, abstractmethod
|
|
5
4
|
from copy import deepcopy
|
|
5
|
+
from datetime import datetime, timezone
|
|
6
6
|
from enum import Enum
|
|
7
7
|
from typing import Optional, Any
|
|
8
8
|
import pandas as pd
|
|
@@ -181,20 +181,21 @@ class ElasticSearch(ABC):
|
|
|
181
181
|
def fill_elk_index_as_bulk(
|
|
182
182
|
self,
|
|
183
183
|
data: list[dict],
|
|
184
|
-
doc_id: str,
|
|
185
184
|
doc_index_name: str,
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
185
|
+
doc_id: Optional[str] = None,
|
|
186
|
+
timestamp: datetime = None,
|
|
187
|
+
date_and_time: Optional[str] = None,
|
|
188
|
+
username: Optional[str] = None,
|
|
189
189
|
chunk_size=1000,
|
|
190
190
|
time_sleep: int = 1
|
|
191
191
|
) -> None: # use as the main function to send data to the elastic search
|
|
192
|
+
timestamp = timestamp or datetime.now(tz=timezone.utc)
|
|
192
193
|
list_of_docs = self._prepare_documents_for_bulk(
|
|
193
194
|
data=data,
|
|
194
|
-
doc_id=doc_id,
|
|
195
195
|
doc_index_name=doc_index_name,
|
|
196
196
|
timestamp=timestamp,
|
|
197
|
-
|
|
197
|
+
doc_id=doc_id or timestamp.strftime('%Y_%m_%dT%H_%M_%S_%f'),
|
|
198
|
+
date_and_time=date_and_time or timestamp.isoformat(),
|
|
198
199
|
username=username
|
|
199
200
|
)
|
|
200
201
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
from typing import Optional, Union, Any
|
|
4
|
+
import psycopg2
|
|
5
|
+
from psycopg2 import extras
|
|
6
|
+
from retrying import retry
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class PostgreSQL:
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
name: Optional[str] = None,
|
|
13
|
+
host: Optional[str] = None,
|
|
14
|
+
port: Optional[str] = None,
|
|
15
|
+
username: Optional[str] = None,
|
|
16
|
+
password: Optional[str] = None
|
|
17
|
+
):
|
|
18
|
+
self.logger = logging.getLogger(self.__class__.__name__)
|
|
19
|
+
|
|
20
|
+
self.name = name or os.getenv("POSTGRESQL_NAME")
|
|
21
|
+
self.host = host or os.getenv("POSTGRESQL_HOST")
|
|
22
|
+
self.port = port or os.getenv("POSTGRESQL_PORT")
|
|
23
|
+
self.username = username or os.getenv("POSTGRESQL_USERNAME")
|
|
24
|
+
self.password = password or os.getenv("POSTGRESQL_PASSWORD")
|
|
25
|
+
|
|
26
|
+
self._client = None
|
|
27
|
+
self._cursor = None
|
|
28
|
+
|
|
29
|
+
self.create_connection()
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def client(self):
|
|
33
|
+
if not self._client or self._client.closed:
|
|
34
|
+
self.logger.warning("Re-establishing PostgreSQL connection")
|
|
35
|
+
self.create_connection()
|
|
36
|
+
return self._client
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def cursor(self):
|
|
40
|
+
if not self._cursor or self._cursor.closed:
|
|
41
|
+
self.logger.warning("Re-creating PostgreSQL cursor")
|
|
42
|
+
self.create_connection()
|
|
43
|
+
return self._cursor
|
|
44
|
+
|
|
45
|
+
@retry(stop_max_attempt_number=3, wait_fixed=180000)
|
|
46
|
+
def create_connection(self):
|
|
47
|
+
self.logger.info(f"Create connection to {self.host}:{self.port}")
|
|
48
|
+
|
|
49
|
+
self._client = psycopg2.connect(
|
|
50
|
+
database=self.name,
|
|
51
|
+
host=self.host,
|
|
52
|
+
port=self.port,
|
|
53
|
+
user=self.username,
|
|
54
|
+
password=self.password,
|
|
55
|
+
)
|
|
56
|
+
self._cursor = self.client.cursor(cursor_factory=extras.DictCursor)
|
|
57
|
+
|
|
58
|
+
def execute_query(self, query: str, params: Optional[Union[tuple, dict[str, Any]]] = None) -> None:
|
|
59
|
+
self.logger.debug(f"Fetch rows from DB by query {query} with params {params}")
|
|
60
|
+
try:
|
|
61
|
+
self.cursor.execute(query, params)
|
|
62
|
+
except psycopg2.ProgrammingError as e:
|
|
63
|
+
raise psycopg2.ProgrammingError(f"Error executing query: {query}") from e
|
|
64
|
+
self.logger.debug(f"Finished to fetch rows by query")
|
|
65
|
+
|
|
66
|
+
def fetch_all(self, query: str, params: Optional[Union[tuple, dict[str, Any]]] = None) -> list[dict[str, Any]]:
|
|
67
|
+
self.execute_query(query, params)
|
|
68
|
+
try:
|
|
69
|
+
results = self.cursor.fetchall()
|
|
70
|
+
except psycopg2.ProgrammingError as e:
|
|
71
|
+
raise psycopg2.ProgrammingError(f"Error fetching rows: {query}") from e
|
|
72
|
+
self.logger.debug(f"Fetched {len(results)} rows")
|
|
73
|
+
return results
|
|
74
|
+
|
|
75
|
+
def close(self):
|
|
76
|
+
self.cursor.close()
|
|
77
|
+
self.client.close()
|
|
78
|
+
|
|
79
|
+
def __enter__(self):
|
|
80
|
+
return self
|
|
81
|
+
|
|
82
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
83
|
+
self.close()
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-databases
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: A Python library for managing and interacting with multiple databases seamlessly.
|
|
5
|
+
Home-page: https://github.com/aviz92/python-databases
|
|
6
|
+
Author: Avi Zaguri
|
|
7
|
+
Author-email:
|
|
8
|
+
Project-URL: Repository, https://github.com/aviz92/python-databases
|
|
9
|
+
Requires-Python: >=3.11
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: setuptools
|
|
13
|
+
Requires-Dist: wheel
|
|
14
|
+
Requires-Dist: dotenv
|
|
15
|
+
Requires-Dist: custom-python-logger
|
|
16
|
+
Requires-Dist: retrying
|
|
17
|
+
Requires-Dist: elasticsearch<9
|
|
18
|
+
Requires-Dist: pandas
|
|
19
|
+
Requires-Dist: psycopg2-binary
|
|
20
|
+
Requires-Dist: pytest
|
|
21
|
+
Dynamic: author
|
|
22
|
+
Dynamic: description
|
|
23
|
+
Dynamic: description-content-type
|
|
24
|
+
Dynamic: home-page
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
Dynamic: project-url
|
|
27
|
+
Dynamic: requires-dist
|
|
28
|
+
Dynamic: requires-python
|
|
29
|
+
Dynamic: summary
|
|
30
|
+
|
|
31
|
+
# Python Databases
|
|
32
|
+
A flexible and extensible Python library that provides a unified interface for interacting with multiple types of databases.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
- ✅ Unified interface for multiple database connectors
|
|
38
|
+
- ✅ Support for:
|
|
39
|
+
- Elasticsearch
|
|
40
|
+
- On-Premises deployments
|
|
41
|
+
- Cloud deployments using `cloud_id`
|
|
42
|
+
- PostgreSQL
|
|
43
|
+
- Basic support with plans for SQLAlchemy integration
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
```bash
|
|
49
|
+
pip install python-databases
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 📌 Roadmap
|
|
55
|
+
|
|
56
|
+
* [x] Elasticsearch support
|
|
57
|
+
- [x] On-Premises deployments
|
|
58
|
+
- [x] Cloud deployments using `cloud_id`
|
|
59
|
+
* [x] PostgreSQL
|
|
60
|
+
- [ ] SQLAlchemy support
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 🤝 Contributing
|
|
65
|
+
If you have a helpful tool, pattern, or improvement to suggest:
|
|
66
|
+
Fork the repo <br>
|
|
67
|
+
Create a new branch <br>
|
|
68
|
+
Submit a pull request <br>
|
|
69
|
+
I welcome additions that promote clean, productive, and maintainable development. <br>
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 🙏 Thanks
|
|
74
|
+
Thanks for exploring this repository! <br>
|
|
75
|
+
Happy coding! <br>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
python_databases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
python_databases/elasticsearch_infrastructure/__init__.py,sha256=zLL3GJwgu5a55TgRhyl_mDbjc-qQBWOskRc0y9diqyw,296
|
|
3
|
+
python_databases/elasticsearch_infrastructure/elasticsearch.py,sha256=U8PVhjImk_S35KJHKEFK7Fl8cL-0A36yzLJ_KgtNTIY,11160
|
|
4
|
+
python_databases/postgresql_infrastructure/__init__.py,sha256=LG-zblOfMP6hVPKsBg0_Vu7Np90aDwZoQtZkamDOsus,46
|
|
5
|
+
python_databases/postgresql_infrastructure/postgresql.py,sha256=Hnn58f6TT2NPOyAou5EvBuH4xE6qGQfYep8wufrC_r8,2816
|
|
6
|
+
python_databases-0.1.2.dist-info/licenses/LICENSE,sha256=cSikHY6SZFsPZSBizCDAJ0-Bjjzxt-JtX6TVbKxwimo,1067
|
|
7
|
+
python_databases-0.1.2.dist-info/METADATA,sha256=wM_Kf2fxKvMk48tlW3Kx-DNnXE06-rwuQTT5hpuHSgc,1792
|
|
8
|
+
python_databases-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
9
|
+
python_databases-0.1.2.dist-info/top_level.txt,sha256=fXcMUntaYJfKeFS7FjQ6DY4WVXYBsgdrDmhOudYs-vg,17
|
|
10
|
+
python_databases-0.1.2.dist-info/RECORD,,
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: python-databases
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: A Python library for managing and interacting with multiple databases seamlessly.
|
|
5
|
-
Home-page: https://github.com/aviz92/python-databases
|
|
6
|
-
Author: Avi Zaguri
|
|
7
|
-
Author-email:
|
|
8
|
-
Project-URL: Repository, https://github.com/aviz92/python-databases
|
|
9
|
-
Requires-Python: >=3.11
|
|
10
|
-
Description-Content-Type: text/markdown
|
|
11
|
-
License-File: LICENSE
|
|
12
|
-
Requires-Dist: setuptools
|
|
13
|
-
Requires-Dist: wheel
|
|
14
|
-
Requires-Dist: dotenv
|
|
15
|
-
Requires-Dist: custom-python-logger
|
|
16
|
-
Requires-Dist: retrying
|
|
17
|
-
Requires-Dist: elasticsearch<9
|
|
18
|
-
Requires-Dist: pandas
|
|
19
|
-
Requires-Dist: psycopg2-binary
|
|
20
|
-
Requires-Dist: pytest
|
|
21
|
-
Dynamic: author
|
|
22
|
-
Dynamic: description
|
|
23
|
-
Dynamic: description-content-type
|
|
24
|
-
Dynamic: home-page
|
|
25
|
-
Dynamic: license-file
|
|
26
|
-
Dynamic: project-url
|
|
27
|
-
Dynamic: requires-dist
|
|
28
|
-
Dynamic: requires-python
|
|
29
|
-
Dynamic: summary
|
|
30
|
-
|
|
31
|
-
# Python Databases
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
python_databases/__init__.py,sha256=NjWdKySjMPaJk8eCFiw54p1ddv42zGj3aVFTVvfkT3E,298
|
|
2
|
-
python_databases/elastic_search_infrastructure/__init__.py,sha256=NjWdKySjMPaJk8eCFiw54p1ddv42zGj3aVFTVvfkT3E,298
|
|
3
|
-
python_databases/elastic_search_infrastructure/elastic_search.py,sha256=1W1jRByLljUDHLE8MqdIOHI_ak6CRKq7YLf09wKwTqQ,10951
|
|
4
|
-
python_databases-0.1.0.dist-info/licenses/LICENSE,sha256=cSikHY6SZFsPZSBizCDAJ0-Bjjzxt-JtX6TVbKxwimo,1067
|
|
5
|
-
python_databases-0.1.0.dist-info/METADATA,sha256=eiuP5xi7JuN_9qYiTWU_0f0huTQ9gfTXj9bX-ZqKwHU,846
|
|
6
|
-
python_databases-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
-
python_databases-0.1.0.dist-info/top_level.txt,sha256=fXcMUntaYJfKeFS7FjQ6DY4WVXYBsgdrDmhOudYs-vg,17
|
|
8
|
-
python_databases-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|