sqliter-py 0.3.0__py3-none-any.whl → 0.5.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.
sqliter/__init__.py CHANGED
@@ -1,4 +1,8 @@
1
- """The 'sqliter' package provides an minimal ORM for the SQLite library."""
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
- """Define constants used in the library."""
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
- """Define custom exceptions for the sqliter package."""
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 exceptions raised by the sqliter package."""
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
- """Raised when the SQLite database connection fails."""
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
- """Raised when an invalid offset value (0 or negative) is used."""
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
- """Raised when an invalid order value is used."""
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
- """Raised when a table cannot be created in the database."""
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
- """Raised when an error occurs during record insertion."""
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
- """Raised when an error occurs during record update."""
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
- """Raised when a record with the specified primary key is not found."""
115
+ """Exception raised when a requested record is not found in the database."""
101
116
 
102
- message_template = "Failed to find a record for key '{}' "
117
+ message_template = "Failed to find that record in the table (key '{}') "
103
118
 
104
119
 
105
120
  class RecordFetchError(SqliterError):
106
- """Raised when an error occurs during record fetching."""
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
- """Raised when an error occurs during record deletion."""
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
- """Raised when an invalid filter field is used in a query."""
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 defines the BaseDBModel class.
1
+ """This module provides the base model class for SQLiter database models.
2
2
 
3
- This should be subclassed by the user to interact with the database.
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,17 +1,34 @@
1
- """Define the Base model class."""
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
 
5
12
  import re
6
- from typing import Any, Optional, TypeVar, Union, get_args, get_origin
13
+ from typing import Any, Optional, TypeVar, Union, cast, get_args, get_origin
7
14
 
8
- from pydantic import BaseModel, ConfigDict
15
+ from pydantic import BaseModel, ConfigDict, Field
9
16
 
10
17
  T = TypeVar("T", bound="BaseDBModel")
11
18
 
12
19
 
13
20
  class BaseDBModel(BaseModel):
14
- """Custom base model for database models."""
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
+ """
30
+
31
+ pk: int = Field(0, description="The mandatory primary key of the table.")
15
32
 
16
33
  model_config = ConfigDict(
17
34
  extra="ignore",
@@ -21,19 +38,31 @@ class BaseDBModel(BaseModel):
21
38
  )
22
39
 
23
40
  class Meta:
24
- """Configure the base model with default options."""
41
+ """Metadata class for configuring database-specific attributes.
42
+
43
+ Attributes:
44
+ create_pk (bool): Whether to create a primary key field.
45
+ primary_key (str): The name of the primary key field.
46
+ table_name (Optional[str]): The name of the database table.
47
+ """
25
48
 
26
- create_pk: bool = (
27
- True # Whether to create an auto-increment primary key
28
- )
29
- primary_key: str = "id" # Default primary key name
30
49
  table_name: Optional[str] = (
31
50
  None # Table name, defaults to class name if not set
32
51
  )
33
52
 
34
53
  @classmethod
35
54
  def model_validate_partial(cls: type[T], obj: dict[str, Any]) -> T:
36
- """Validate a partial model object."""
55
+ """Validate and create a model instance from partial data.
56
+
57
+ This method allows for the creation of a model instance even when
58
+ not all fields are present in the input data.
59
+
60
+ Args:
61
+ obj: A dictionary of field names and values.
62
+
63
+ Returns:
64
+ An instance of the model class with the provided data.
65
+ """
37
66
  converted_obj: dict[str, Any] = {}
38
67
  for field_name, value in obj.items():
39
68
  field = cls.model_fields[field_name]
@@ -58,16 +87,17 @@ class BaseDBModel(BaseModel):
58
87
  else:
59
88
  converted_obj[field_name] = field_type(value)
60
89
 
61
- return cls.model_construct(**converted_obj)
90
+ return cast(T, cls.model_construct(**converted_obj))
62
91
 
63
92
  @classmethod
64
93
  def get_table_name(cls) -> str:
65
- """Get the table name from the Meta, or generate one.
94
+ """Get the database table name for the model.
95
+
96
+ This method determines the table name based on the Meta configuration
97
+ or derives it from the class name if not explicitly set.
66
98
 
67
99
  Returns:
68
- str: The table name, either specified in the Meta class or
69
- generated by converting the class name to pluralized snake_case
70
- and removing any 'Model' suffix.
100
+ The name of the database table for this model.
71
101
  """
72
102
  table_name: str | None = getattr(cls.Meta, "table_name", None)
73
103
  if table_name is not None:
@@ -95,10 +125,10 @@ class BaseDBModel(BaseModel):
95
125
 
96
126
  @classmethod
97
127
  def get_primary_key(cls) -> str:
98
- """Get the primary key from the Meta class or default to 'id'."""
99
- return getattr(cls.Meta, "primary_key", "id")
128
+ """Returns the mandatory primary key, always 'pk'."""
129
+ return "pk"
100
130
 
101
131
  @classmethod
102
132
  def should_create_pk(cls) -> bool:
103
- """Check whether the model should create an auto-increment ID."""
104
- return getattr(cls.Meta, "create_pk", True)
133
+ """Returns True since the primary key is always created."""
134
+ return True
sqliter/query/__init__.py CHANGED
@@ -1,4 +1,8 @@
1
- """Define the 'QueryBuilder' class for building SQL queries."""
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