sqliter-py 0.3.0__py3-none-any.whl → 0.4.0__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.
Potentially problematic release.
This version of sqliter-py might be problematic. Click here for more details.
- sqliter/__init__.py +5 -1
- sqliter/constants.py +18 -1
- sqliter/exceptions.py +39 -12
- sqliter/helpers.py +35 -0
- sqliter/model/__init__.py +3 -2
- sqliter/model/model.py +50 -10
- sqliter/query/__init__.py +5 -1
- sqliter/query/query.py +278 -36
- sqliter/sqliter.py +317 -38
- sqliter_py-0.4.0.dist-info/METADATA +196 -0
- sqliter_py-0.4.0.dist-info/RECORD +13 -0
- sqliter_py-0.3.0.dist-info/METADATA +0 -601
- sqliter_py-0.3.0.dist-info/RECORD +0 -12
- {sqliter_py-0.3.0.dist-info → sqliter_py-0.4.0.dist-info}/WHEEL +0 -0
- {sqliter_py-0.3.0.dist-info → sqliter_py-0.4.0.dist-info}/licenses/LICENSE.txt +0 -0
sqliter/__init__.py
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""SQLiter: A lightweight ORM-like library for SQLite databases in Python.
|
|
2
|
+
|
|
3
|
+
This module provides the main SqliterDB class for interacting with
|
|
4
|
+
SQLite databases using Pydantic models.
|
|
5
|
+
"""
|
|
2
6
|
|
|
3
7
|
from .sqliter import SqliterDB
|
|
4
8
|
|
sqliter/constants.py
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Constant values and mappings used throughout SQLiter.
|
|
2
2
|
|
|
3
|
+
This module defines constant dictionaries that map SQLiter-specific
|
|
4
|
+
concepts to their SQLite equivalents. It includes mappings for query
|
|
5
|
+
operators and data types, which are crucial for translating between
|
|
6
|
+
Pydantic models and SQLite database operations.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
# A dictionary mapping SQLiter filter operators to their corresponding SQL
|
|
10
|
+
# operators.
|
|
3
11
|
OPERATOR_MAPPING = {
|
|
4
12
|
"__lt": "<",
|
|
5
13
|
"__lte": "<=",
|
|
@@ -18,3 +26,12 @@ OPERATOR_MAPPING = {
|
|
|
18
26
|
"__iendswith": "LIKE",
|
|
19
27
|
"__icontains": "LIKE",
|
|
20
28
|
}
|
|
29
|
+
|
|
30
|
+
# A dictionary mapping Python types to their corresponding SQLite column types.
|
|
31
|
+
SQLITE_TYPE_MAPPING = {
|
|
32
|
+
int: "INTEGER",
|
|
33
|
+
float: "REAL",
|
|
34
|
+
str: "TEXT",
|
|
35
|
+
bool: "INTEGER", # SQLite stores booleans as integers (0 or 1)
|
|
36
|
+
bytes: "BLOB",
|
|
37
|
+
}
|
sqliter/exceptions.py
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Custom exception classes for SQLiter error handling.
|
|
2
|
+
|
|
3
|
+
This module defines a hierarchy of exception classes specific to
|
|
4
|
+
SQLiter operations. These exceptions provide detailed error information
|
|
5
|
+
for various scenarios such as connection issues, invalid queries,
|
|
6
|
+
and CRUD operation failures, enabling more precise error handling
|
|
7
|
+
in applications using SQLiter.
|
|
8
|
+
"""
|
|
2
9
|
|
|
3
10
|
import os
|
|
4
11
|
import sys
|
|
@@ -6,7 +13,15 @@ import traceback
|
|
|
6
13
|
|
|
7
14
|
|
|
8
15
|
class SqliterError(Exception):
|
|
9
|
-
"""Base class for all
|
|
16
|
+
"""Base exception class for all SQLiter-specific errors.
|
|
17
|
+
|
|
18
|
+
This class serves as the parent for all custom exceptions in SQLiter,
|
|
19
|
+
providing a consistent interface and message formatting.
|
|
20
|
+
|
|
21
|
+
Attributes:
|
|
22
|
+
message_template (str): A template string for the error message.
|
|
23
|
+
original_exception (Exception): The original exception that was caught.
|
|
24
|
+
"""
|
|
10
25
|
|
|
11
26
|
message_template: str = "An error occurred in the SQLiter package."
|
|
12
27
|
|
|
@@ -59,13 +74,13 @@ class SqliterError(Exception):
|
|
|
59
74
|
|
|
60
75
|
|
|
61
76
|
class DatabaseConnectionError(SqliterError):
|
|
62
|
-
"""
|
|
77
|
+
"""Exception raised when a database connection cannot be established."""
|
|
63
78
|
|
|
64
79
|
message_template = "Failed to connect to the database: '{}'"
|
|
65
80
|
|
|
66
81
|
|
|
67
82
|
class InvalidOffsetError(SqliterError):
|
|
68
|
-
"""
|
|
83
|
+
"""Exception raised when an invalid offset value is provided."""
|
|
69
84
|
|
|
70
85
|
message_template = (
|
|
71
86
|
"Invalid offset value: '{}'. Offset must be a positive integer."
|
|
@@ -73,48 +88,60 @@ class InvalidOffsetError(SqliterError):
|
|
|
73
88
|
|
|
74
89
|
|
|
75
90
|
class InvalidOrderError(SqliterError):
|
|
76
|
-
"""
|
|
91
|
+
"""Exception raised when an invalid order specification is provided."""
|
|
77
92
|
|
|
78
93
|
message_template = "Invalid order value - {}"
|
|
79
94
|
|
|
80
95
|
|
|
81
96
|
class TableCreationError(SqliterError):
|
|
82
|
-
"""
|
|
97
|
+
"""Exception raised when a table cannot be created in the database."""
|
|
83
98
|
|
|
84
99
|
message_template = "Failed to create the table: '{}'"
|
|
85
100
|
|
|
86
101
|
|
|
87
102
|
class RecordInsertionError(SqliterError):
|
|
88
|
-
"""
|
|
103
|
+
"""Exception raised when a record cannot be inserted into the database."""
|
|
89
104
|
|
|
90
105
|
message_template = "Failed to insert record into table: '{}'"
|
|
91
106
|
|
|
92
107
|
|
|
93
108
|
class RecordUpdateError(SqliterError):
|
|
94
|
-
"""
|
|
109
|
+
"""Exception raised when a record cannot be updated in the database."""
|
|
95
110
|
|
|
96
111
|
message_template = "Failed to update record in table: '{}'"
|
|
97
112
|
|
|
98
113
|
|
|
99
114
|
class RecordNotFoundError(SqliterError):
|
|
100
|
-
"""
|
|
115
|
+
"""Exception raised when a requested record is not found in the database."""
|
|
101
116
|
|
|
102
117
|
message_template = "Failed to find a record for key '{}' "
|
|
103
118
|
|
|
104
119
|
|
|
105
120
|
class RecordFetchError(SqliterError):
|
|
106
|
-
"""
|
|
121
|
+
"""Exception raised on an error fetching records from the database."""
|
|
107
122
|
|
|
108
123
|
message_template = "Failed to fetch record from table: '{}'"
|
|
109
124
|
|
|
110
125
|
|
|
111
126
|
class RecordDeletionError(SqliterError):
|
|
112
|
-
"""
|
|
127
|
+
"""Exception raised when a record cannot be deleted from the database."""
|
|
113
128
|
|
|
114
129
|
message_template = "Failed to delete record from table: '{}'"
|
|
115
130
|
|
|
116
131
|
|
|
117
132
|
class InvalidFilterError(SqliterError):
|
|
118
|
-
"""
|
|
133
|
+
"""Exception raised when an invalid filter is applied to a query."""
|
|
119
134
|
|
|
120
135
|
message_template = "Failed to apply filter: invalid field '{}'"
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class TableDeletionError(SqliterError):
|
|
139
|
+
"""Raised when a table cannot be deleted from the database."""
|
|
140
|
+
|
|
141
|
+
message_template = "Failed to delete the table: '{}'"
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class SqlExecutionError(SqliterError):
|
|
145
|
+
"""Raised when an SQL execution fails."""
|
|
146
|
+
|
|
147
|
+
message_template = "Failed to execute SQL: '{}'"
|
sqliter/helpers.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Utility functions for SQLiter internal operations.
|
|
2
|
+
|
|
3
|
+
This module provides helper functions used across the SQLiter library,
|
|
4
|
+
primarily for type inference and mapping between Python and SQLite
|
|
5
|
+
data types. These utilities support the core functionality of model
|
|
6
|
+
to database schema translation.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
11
|
+
from sqliter.constants import SQLITE_TYPE_MAPPING
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def infer_sqlite_type(field_type: Union[type, None]) -> str:
|
|
15
|
+
"""Infer the SQLite column type based on the Python type.
|
|
16
|
+
|
|
17
|
+
This function maps Python types to their corresponding SQLite column
|
|
18
|
+
types. It's used when creating database tables to ensure that the
|
|
19
|
+
correct SQLite types are used for each field.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
field_type: The Python type of the field, or None.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
A string representing the corresponding SQLite column type.
|
|
26
|
+
|
|
27
|
+
Note:
|
|
28
|
+
If the input type is None or not recognized, it defaults to 'TEXT'.
|
|
29
|
+
"""
|
|
30
|
+
# If field_type is None, default to TEXT
|
|
31
|
+
if field_type is None:
|
|
32
|
+
return "TEXT"
|
|
33
|
+
|
|
34
|
+
# Map the simplified type to an SQLite type
|
|
35
|
+
return SQLITE_TYPE_MAPPING.get(field_type, "TEXT")
|
sqliter/model/__init__.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
"""This module
|
|
1
|
+
"""This module provides the base model class for SQLiter database models.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
It exports the BaseDBModel class, which is used to define database
|
|
4
|
+
models in SQLiter applications.
|
|
4
5
|
"""
|
|
5
6
|
|
|
6
7
|
from .model import BaseDBModel
|
sqliter/model/model.py
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Defines the base model class for SQLiter ORM functionality.
|
|
2
|
+
|
|
3
|
+
This module provides the BaseDBModel class, which extends Pydantic's
|
|
4
|
+
BaseModel to add SQLiter-specific functionality. It includes methods
|
|
5
|
+
for table name inference, primary key management, and partial model
|
|
6
|
+
validation, forming the foundation for defining database-mapped models
|
|
7
|
+
in SQLiter applications.
|
|
8
|
+
"""
|
|
2
9
|
|
|
3
10
|
from __future__ import annotations
|
|
4
11
|
|
|
@@ -11,7 +18,15 @@ T = TypeVar("T", bound="BaseDBModel")
|
|
|
11
18
|
|
|
12
19
|
|
|
13
20
|
class BaseDBModel(BaseModel):
|
|
14
|
-
"""
|
|
21
|
+
"""Base model class for SQLiter database models.
|
|
22
|
+
|
|
23
|
+
This class extends Pydantic's BaseModel to provide additional functionality
|
|
24
|
+
for database operations. It includes configuration options and methods
|
|
25
|
+
specific to SQLiter's ORM-like functionality.
|
|
26
|
+
|
|
27
|
+
This should not be used directly, but should be inherited by subclasses
|
|
28
|
+
representing database models.
|
|
29
|
+
"""
|
|
15
30
|
|
|
16
31
|
model_config = ConfigDict(
|
|
17
32
|
extra="ignore",
|
|
@@ -21,7 +36,13 @@ class BaseDBModel(BaseModel):
|
|
|
21
36
|
)
|
|
22
37
|
|
|
23
38
|
class Meta:
|
|
24
|
-
"""
|
|
39
|
+
"""Metadata class for configuring database-specific attributes.
|
|
40
|
+
|
|
41
|
+
Attributes:
|
|
42
|
+
create_pk (bool): Whether to create a primary key field.
|
|
43
|
+
primary_key (str): The name of the primary key field.
|
|
44
|
+
table_name (Optional[str]): The name of the database table.
|
|
45
|
+
"""
|
|
25
46
|
|
|
26
47
|
create_pk: bool = (
|
|
27
48
|
True # Whether to create an auto-increment primary key
|
|
@@ -33,7 +54,17 @@ class BaseDBModel(BaseModel):
|
|
|
33
54
|
|
|
34
55
|
@classmethod
|
|
35
56
|
def model_validate_partial(cls: type[T], obj: dict[str, Any]) -> T:
|
|
36
|
-
"""Validate a partial
|
|
57
|
+
"""Validate and create a model instance from partial data.
|
|
58
|
+
|
|
59
|
+
This method allows for the creation of a model instance even when
|
|
60
|
+
not all fields are present in the input data.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
obj: A dictionary of field names and values.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
An instance of the model class with the provided data.
|
|
67
|
+
"""
|
|
37
68
|
converted_obj: dict[str, Any] = {}
|
|
38
69
|
for field_name, value in obj.items():
|
|
39
70
|
field = cls.model_fields[field_name]
|
|
@@ -62,12 +93,13 @@ class BaseDBModel(BaseModel):
|
|
|
62
93
|
|
|
63
94
|
@classmethod
|
|
64
95
|
def get_table_name(cls) -> str:
|
|
65
|
-
"""Get the table name
|
|
96
|
+
"""Get the database table name for the model.
|
|
97
|
+
|
|
98
|
+
This method determines the table name based on the Meta configuration
|
|
99
|
+
or derives it from the class name if not explicitly set.
|
|
66
100
|
|
|
67
101
|
Returns:
|
|
68
|
-
|
|
69
|
-
generated by converting the class name to pluralized snake_case
|
|
70
|
-
and removing any 'Model' suffix.
|
|
102
|
+
The name of the database table for this model.
|
|
71
103
|
"""
|
|
72
104
|
table_name: str | None = getattr(cls.Meta, "table_name", None)
|
|
73
105
|
if table_name is not None:
|
|
@@ -95,10 +127,18 @@ class BaseDBModel(BaseModel):
|
|
|
95
127
|
|
|
96
128
|
@classmethod
|
|
97
129
|
def get_primary_key(cls) -> str:
|
|
98
|
-
"""Get the primary key
|
|
130
|
+
"""Get the primary key field name for the model.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
The name of the primary key field.
|
|
134
|
+
"""
|
|
99
135
|
return getattr(cls.Meta, "primary_key", "id")
|
|
100
136
|
|
|
101
137
|
@classmethod
|
|
102
138
|
def should_create_pk(cls) -> bool:
|
|
103
|
-
"""
|
|
139
|
+
"""Determine if a primary key should be automatically created.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
True if a primary key should be created, False otherwise.
|
|
143
|
+
"""
|
|
104
144
|
return getattr(cls.Meta, "create_pk", True)
|
sqliter/query/__init__.py
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""This module provides the query building functionality for SQLiter.
|
|
2
|
+
|
|
3
|
+
It exports the QueryBuilder class, which is used to construct and
|
|
4
|
+
execute database queries in SQLiter.
|
|
5
|
+
"""
|
|
2
6
|
|
|
3
7
|
from .query import QueryBuilder
|
|
4
8
|
|