database-wrapper-sqlite 0.2.17__py3-none-any.whl → 0.2.23__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.
- database_wrapper_sqlite/__init__.py +10 -4
- database_wrapper_sqlite/connector.py +72 -21
- database_wrapper_sqlite/db_wrapper_sqlite.py +76 -0
- {database_wrapper_sqlite-0.2.17.dist-info → database_wrapper_sqlite-0.2.23.dist-info}/METADATA +2 -2
- database_wrapper_sqlite-0.2.23.dist-info/RECORD +8 -0
- database_wrapper_sqlite-0.2.17.dist-info/RECORD +0 -7
- {database_wrapper_sqlite-0.2.17.dist-info → database_wrapper_sqlite-0.2.23.dist-info}/WHEEL +0 -0
- {database_wrapper_sqlite-0.2.17.dist-info → database_wrapper_sqlite-0.2.23.dist-info}/top_level.txt +0 -0
|
@@ -9,7 +9,8 @@ Part of the database_wrapper package
|
|
|
9
9
|
import logging
|
|
10
10
|
|
|
11
11
|
# from .db_wrapper_sqlite import DBWrapperSqlite
|
|
12
|
-
from .connector import Sqlite, SqliteConfig
|
|
12
|
+
from .connector import Sqlite, SqliteConfig, SqliteTypedDictCursor
|
|
13
|
+
from .db_wrapper_sqlite import DBWrapperSqlite
|
|
13
14
|
|
|
14
15
|
# Set the logger to a quiet default, can be enabled if needed
|
|
15
16
|
logger = logging.getLogger("database_wrapper_sqlite")
|
|
@@ -18,7 +19,12 @@ if logger.level == logging.NOTSET:
|
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
__all__ = [
|
|
21
|
-
#
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
# Wrappers
|
|
23
|
+
DBWrapperSqlite,
|
|
24
|
+
# Connectors
|
|
25
|
+
Sqlite,
|
|
26
|
+
# Connection and Cursor types
|
|
27
|
+
SqliteTypedDictCursor,
|
|
28
|
+
# Helpers
|
|
29
|
+
SqliteConfig,
|
|
24
30
|
]
|
|
@@ -1,48 +1,99 @@
|
|
|
1
|
-
|
|
1
|
+
import sqlite3
|
|
2
|
+
from typing import Any, NotRequired, TypedDict, cast
|
|
2
3
|
|
|
3
4
|
from database_wrapper import DatabaseBackend
|
|
4
5
|
|
|
5
6
|
|
|
7
|
+
def dict_factory(cursor: sqlite3.Cursor, row: tuple) -> dict[str, Any]:
|
|
8
|
+
fields = [col[0] for col in cursor.description]
|
|
9
|
+
return dict(zip(fields, row, strict=False))
|
|
10
|
+
|
|
11
|
+
|
|
6
12
|
class SqliteConfig(TypedDict):
|
|
7
13
|
database: str
|
|
14
|
+
timeout: NotRequired[float]
|
|
15
|
+
isolation_level: NotRequired[str | None]
|
|
8
16
|
kwargs: NotRequired[dict[str, Any]]
|
|
9
17
|
|
|
10
18
|
|
|
11
|
-
|
|
12
|
-
class Sqlite(DatabaseBackend):
|
|
19
|
+
class SqliteTypedDictCursor(sqlite3.Cursor):
|
|
13
20
|
"""
|
|
14
|
-
|
|
21
|
+
Type hint wrapper only. At runtime, this is just a sqlite3.Cursor
|
|
22
|
+
that happens to produce dicts because of the row_factory.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def fetchone(self) -> dict[str, Any] | None:
|
|
26
|
+
return super().fetchone() # type: ignore
|
|
15
27
|
|
|
16
|
-
|
|
17
|
-
|
|
28
|
+
def fetchall(self) -> list[dict[str, Any]]:
|
|
29
|
+
return super().fetchall() # type: ignore
|
|
18
30
|
|
|
19
|
-
|
|
20
|
-
|
|
31
|
+
def __iter__(self) -> "SqliteTypedDictCursor":
|
|
32
|
+
return self
|
|
33
|
+
|
|
34
|
+
def __next__(self) -> dict[str, Any]:
|
|
35
|
+
return super().__next__() # type: ignore
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Sqlite(DatabaseBackend):
|
|
39
|
+
"""
|
|
40
|
+
SQLite database backend
|
|
41
|
+
|
|
42
|
+
:param config: Configuration for SQLite
|
|
43
|
+
:type config: SqliteConfig
|
|
21
44
|
"""
|
|
22
45
|
|
|
23
46
|
config: SqliteConfig
|
|
47
|
+
connection: sqlite3.Connection
|
|
48
|
+
cursor: SqliteTypedDictCursor
|
|
24
49
|
|
|
25
|
-
|
|
26
|
-
|
|
50
|
+
##################
|
|
51
|
+
### Connection ###
|
|
52
|
+
##################
|
|
27
53
|
|
|
28
54
|
def open(self) -> None:
|
|
29
|
-
|
|
30
|
-
if hasattr(self, "connection") and self.connection:
|
|
31
|
-
self.close()
|
|
55
|
+
self.logger.debug("Connecting to DB")
|
|
32
56
|
|
|
33
|
-
|
|
34
|
-
if "kwargs" not in self.config or not self.config["kwargs"]:
|
|
57
|
+
if "kwargs" not in self.config:
|
|
35
58
|
self.config["kwargs"] = {}
|
|
36
59
|
|
|
37
|
-
|
|
60
|
+
# Default timeout to 5.0 seconds if not specified
|
|
61
|
+
timeout = self.config.get("timeout", 5.0)
|
|
38
62
|
|
|
39
|
-
|
|
40
|
-
|
|
63
|
+
# Default isolation_level to None (autocommit mode via library, though SQLite is tricky with this)
|
|
64
|
+
# or leave as default. Let's respect config or default to standard.
|
|
65
|
+
isolation_level = self.config.get("isolation_level", None)
|
|
66
|
+
|
|
67
|
+
self.connection = sqlite3.connect(
|
|
68
|
+
self.config["database"],
|
|
69
|
+
timeout=timeout,
|
|
70
|
+
isolation_level=isolation_level,
|
|
71
|
+
**self.config["kwargs"],
|
|
41
72
|
)
|
|
42
73
|
|
|
74
|
+
# Set row factory to return dicts
|
|
75
|
+
self.connection.row_factory = dict_factory
|
|
76
|
+
|
|
77
|
+
# Create cursor
|
|
78
|
+
self.cursor = cast(SqliteTypedDictCursor, self.connection.cursor())
|
|
79
|
+
|
|
80
|
+
def ping(self) -> bool:
|
|
81
|
+
try:
|
|
82
|
+
self.cursor.execute("SELECT 1")
|
|
83
|
+
self.cursor.fetchone()
|
|
84
|
+
except Exception as e:
|
|
85
|
+
self.logger.debug(f"Error while pinging the database: {e}")
|
|
86
|
+
return False
|
|
87
|
+
|
|
88
|
+
return True
|
|
89
|
+
|
|
90
|
+
############
|
|
91
|
+
### Data ###
|
|
92
|
+
############
|
|
93
|
+
|
|
43
94
|
def last_insert_id(self) -> int:
|
|
44
95
|
assert self.cursor, "Cursor is not initialized"
|
|
45
|
-
return self.cursor.lastrowid
|
|
96
|
+
return self.cursor.lastrowid or 0
|
|
46
97
|
|
|
47
98
|
def affected_rows(self) -> int:
|
|
48
99
|
assert self.cursor, "Cursor is not initialized"
|
|
@@ -52,12 +103,12 @@ class Sqlite(DatabaseBackend):
|
|
|
52
103
|
"""Commit DB queries"""
|
|
53
104
|
assert self.connection, "Connection is not initialized"
|
|
54
105
|
|
|
55
|
-
self.logger.debug("Commit DB queries
|
|
106
|
+
self.logger.debug("Commit DB queries")
|
|
56
107
|
self.connection.commit()
|
|
57
108
|
|
|
58
109
|
def rollback(self) -> None:
|
|
59
110
|
"""Rollback DB queries"""
|
|
60
111
|
assert self.connection, "Connection is not initialized"
|
|
61
112
|
|
|
62
|
-
self.logger.debug("Rollback DB queries
|
|
113
|
+
self.logger.debug("Rollback DB queries")
|
|
63
114
|
self.connection.rollback()
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from database_wrapper import DBWrapper
|
|
5
|
+
|
|
6
|
+
from .connector import SqliteTypedDictCursor
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DBWrapperSqlite(DBWrapper):
|
|
10
|
+
"""Wrapper for SQLite database"""
|
|
11
|
+
|
|
12
|
+
db_cursor: SqliteTypedDictCursor | None
|
|
13
|
+
""" SQLite cursor object """
|
|
14
|
+
|
|
15
|
+
#######################
|
|
16
|
+
### Class lifecycle ###
|
|
17
|
+
#######################
|
|
18
|
+
|
|
19
|
+
# Meta methods
|
|
20
|
+
# We are overriding the __init__ method for the type hinting
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
db_cursor: SqliteTypedDictCursor | None = None,
|
|
24
|
+
logger: logging.Logger | None = None,
|
|
25
|
+
):
|
|
26
|
+
"""
|
|
27
|
+
Initializes a new instance of the DBWrapper class.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
db_cursor (SqliteTypedDictCursor): The SQLite database cursor object.
|
|
31
|
+
logger (logging.Logger, optional): The logger object. Defaults to None.
|
|
32
|
+
"""
|
|
33
|
+
super().__init__(db_cursor, logger)
|
|
34
|
+
|
|
35
|
+
###############
|
|
36
|
+
### Setters ###
|
|
37
|
+
###############
|
|
38
|
+
|
|
39
|
+
def set_db_cursor(self, db_cursor: SqliteTypedDictCursor | None) -> None:
|
|
40
|
+
"""
|
|
41
|
+
Updates the database cursor object.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
db_cursor (SqliteTypedDictCursor): The new database cursor object.
|
|
45
|
+
"""
|
|
46
|
+
super().set_db_cursor(db_cursor)
|
|
47
|
+
|
|
48
|
+
######################
|
|
49
|
+
### Helper methods ###
|
|
50
|
+
######################
|
|
51
|
+
|
|
52
|
+
def log_query(
|
|
53
|
+
self,
|
|
54
|
+
cursor: SqliteTypedDictCursor,
|
|
55
|
+
query: Any,
|
|
56
|
+
params: tuple[Any, ...],
|
|
57
|
+
) -> None:
|
|
58
|
+
"""
|
|
59
|
+
Logs the given query and parameters.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
cursor (SqliteTypedDictCursor): The cursor used to execute the query.
|
|
63
|
+
query (Any): The query to log.
|
|
64
|
+
params (tuple[Any, ...]): The parameters to log.
|
|
65
|
+
"""
|
|
66
|
+
# sqlite3 does not support mogrify, so we just log query and params
|
|
67
|
+
logging.getLogger().debug(f"Query: {query} with params: {params}")
|
|
68
|
+
|
|
69
|
+
#####################
|
|
70
|
+
### Query methods ###
|
|
71
|
+
#####################
|
|
72
|
+
|
|
73
|
+
def limit_query(self, offset: int = 0, limit: int = 100) -> str | None:
|
|
74
|
+
if limit == 0:
|
|
75
|
+
return None
|
|
76
|
+
return f"LIMIT {limit} OFFSET {offset}"
|
{database_wrapper_sqlite-0.2.17.dist-info → database_wrapper_sqlite-0.2.23.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: database_wrapper_sqlite
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.23
|
|
4
4
|
Summary: database_wrapper for PostgreSQL database
|
|
5
5
|
Author-email: Gints Murans <gm@gm.lv>
|
|
6
6
|
License: GNU General Public License v3.0 (GPL-3.0)
|
|
@@ -32,7 +32,7 @@ Classifier: Topic :: Software Development
|
|
|
32
32
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
33
33
|
Requires-Python: >=3.8
|
|
34
34
|
Description-Content-Type: text/markdown
|
|
35
|
-
Requires-Dist: database_wrapper==0.2.
|
|
35
|
+
Requires-Dist: database_wrapper==0.2.23
|
|
36
36
|
|
|
37
37
|
# database_wrapper_sqlite
|
|
38
38
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
database_wrapper_sqlite/__init__.py,sha256=YzrxZ4CaMD_OQqQMYjMtMZzzC7MR5D9MXmahTMjTVhI,678
|
|
2
|
+
database_wrapper_sqlite/connector.py,sha256=pZX3vYO1HLjAYAjxdy1PJb0zFa8vQN5tnT1NAP3ZEXM,3256
|
|
3
|
+
database_wrapper_sqlite/db_wrapper_sqlite.py,sha256=CvB-qZYTGr2r6cIbDtbH-tiUrM5U6Vw6mFI5IU57okU,2133
|
|
4
|
+
database_wrapper_sqlite/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
database_wrapper_sqlite-0.2.23.dist-info/METADATA,sha256=eAb2vMdKTk6-wJzTK6ZOq_w9CHQ70PWfieRJnKrpOqQ,2823
|
|
6
|
+
database_wrapper_sqlite-0.2.23.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
+
database_wrapper_sqlite-0.2.23.dist-info/top_level.txt,sha256=53mm8n6modSF012UMCHllRLbCLajpC0uDwHE0WU1Lxo,24
|
|
8
|
+
database_wrapper_sqlite-0.2.23.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
database_wrapper_sqlite/__init__.py,sha256=MNI7MORv3RmKZ-W3keehfa2fw_WpGrCOb2tZ99KNrJ4,509
|
|
2
|
-
database_wrapper_sqlite/connector.py,sha256=kZtVpBLtdCof5Pjj8fS8EMp0R_z-NQo_EV2kH_crRa0,1635
|
|
3
|
-
database_wrapper_sqlite/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
database_wrapper_sqlite-0.2.17.dist-info/METADATA,sha256=DWNNhiCyk6VRhGByzv8cYUAAY-ey4rPD-t1pKWLCVXc,2823
|
|
5
|
-
database_wrapper_sqlite-0.2.17.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
-
database_wrapper_sqlite-0.2.17.dist-info/top_level.txt,sha256=53mm8n6modSF012UMCHllRLbCLajpC0uDwHE0WU1Lxo,24
|
|
7
|
-
database_wrapper_sqlite-0.2.17.dist-info/RECORD,,
|
|
File without changes
|
{database_wrapper_sqlite-0.2.17.dist-info → database_wrapper_sqlite-0.2.23.dist-info}/top_level.txt
RENAMED
|
File without changes
|