fastapi-sqlalchemy-ease 0.1.3__py3-none-any.whl → 0.1.5__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.
- fastapi_sqlalchemy_ease/__init__.py +1 -1
- fastapi_sqlalchemy_ease/core.py +43 -19
- fastapi_sqlalchemy_ease-0.1.5.dist-info/METADATA +109 -0
- fastapi_sqlalchemy_ease-0.1.5.dist-info/RECORD +8 -0
- fastapi_sqlalchemy_ease-0.1.3.dist-info/METADATA +0 -11
- fastapi_sqlalchemy_ease-0.1.3.dist-info/RECORD +0 -8
- {fastapi_sqlalchemy_ease-0.1.3.dist-info → fastapi_sqlalchemy_ease-0.1.5.dist-info}/WHEEL +0 -0
- {fastapi_sqlalchemy_ease-0.1.3.dist-info → fastapi_sqlalchemy_ease-0.1.5.dist-info}/licenses/LICENSE +0 -0
- {fastapi_sqlalchemy_ease-0.1.3.dist-info → fastapi_sqlalchemy_ease-0.1.5.dist-info}/top_level.txt +0 -0
fastapi_sqlalchemy_ease/core.py
CHANGED
|
@@ -6,7 +6,8 @@ from sqlalchemy import (
|
|
|
6
6
|
Numeric,
|
|
7
7
|
ForeignKey,
|
|
8
8
|
UniqueConstraint, CheckConstraint,
|
|
9
|
-
Index, Table
|
|
9
|
+
Index, Table,
|
|
10
|
+
func, and_, any_, not_, or_, select, update, delete, desc, asc
|
|
10
11
|
)
|
|
11
12
|
from sqlalchemy.orm import declarative_base, sessionmaker, Session, relationship
|
|
12
13
|
from typing import Generator, Optional
|
|
@@ -32,6 +33,24 @@ class SQLAlchemy:
|
|
|
32
33
|
LargeBinary = LargeBinary
|
|
33
34
|
Numeric = Numeric
|
|
34
35
|
|
|
36
|
+
'''Logic and Boolean operators'''
|
|
37
|
+
and_ = and_
|
|
38
|
+
or_ = or_
|
|
39
|
+
not_ = not_
|
|
40
|
+
|
|
41
|
+
'''SQL Functions (count, now, max, min, etc.)'''
|
|
42
|
+
func = func
|
|
43
|
+
|
|
44
|
+
'''Query Execution Utilities'''
|
|
45
|
+
select = select
|
|
46
|
+
update = update
|
|
47
|
+
delete = delete
|
|
48
|
+
|
|
49
|
+
'''ordering'''
|
|
50
|
+
desc = desc
|
|
51
|
+
asc = asc
|
|
52
|
+
|
|
53
|
+
|
|
35
54
|
'''Relationships and Constraints'''
|
|
36
55
|
ForeignKey = ForeignKey
|
|
37
56
|
UniqueConstraint = UniqueConstraint
|
|
@@ -43,18 +62,21 @@ class SQLAlchemy:
|
|
|
43
62
|
def __new__(cls):
|
|
44
63
|
if cls._instance is None:
|
|
45
64
|
cls._instance = super().__new__(cls)
|
|
65
|
+
cls._instance._Model = declarative_base()
|
|
46
66
|
return cls._instance
|
|
47
67
|
|
|
48
68
|
|
|
49
69
|
def __init__(self):
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
70
|
+
if not hasattr(self, '_initialized_vars'):
|
|
71
|
+
# Everything starts as None Until db.init_app() is called
|
|
72
|
+
self.engine = None
|
|
73
|
+
self._SessionLocal = None
|
|
74
|
+
self.session = None
|
|
75
|
+
self._initialized = False
|
|
76
|
+
self._initialized_vars = True
|
|
55
77
|
|
|
56
78
|
|
|
57
|
-
def init_app(self, DATABASE_URI: str,
|
|
79
|
+
def init_app(self, DATABASE_URI: str, **kwargs):
|
|
58
80
|
'''
|
|
59
81
|
Docstring for init_app
|
|
60
82
|
|
|
@@ -64,12 +86,16 @@ class SQLAlchemy:
|
|
|
64
86
|
connect_args: used only when initializing sqlite db
|
|
65
87
|
'''
|
|
66
88
|
|
|
67
|
-
engine_kwargs={
|
|
89
|
+
engine_kwargs={
|
|
90
|
+
"pool_pre_ping": True,
|
|
91
|
+
}
|
|
68
92
|
|
|
69
|
-
if
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
engine_kwargs[
|
|
93
|
+
# Only add pooling if NOT using SQLite
|
|
94
|
+
if not DATABASE_URI.startswith("sqlite"):
|
|
95
|
+
engine_kwargs["pool_size"] = kwargs.get("pool_size", 10)
|
|
96
|
+
engine_kwargs["max_overflow"] = kwargs.get("max_overflow", 20)
|
|
97
|
+
|
|
98
|
+
engine_kwargs.update(kwargs)
|
|
73
99
|
|
|
74
100
|
# Engine connection to database
|
|
75
101
|
self.engine = create_engine(DATABASE_URI, **engine_kwargs)
|
|
@@ -77,8 +103,9 @@ class SQLAlchemy:
|
|
|
77
103
|
# SessionLocal - Factory data creates new sessions
|
|
78
104
|
self._SessionLocal = sessionmaker(autoflush=False ,bind=self.engine)
|
|
79
105
|
|
|
80
|
-
|
|
81
|
-
self.
|
|
106
|
+
from sqlalchemy.orm import scoped_session
|
|
107
|
+
self.session = scoped_session(self._SessionLocal)
|
|
108
|
+
self._Model.query = self.session.query_property()
|
|
82
109
|
|
|
83
110
|
self._initialized = True
|
|
84
111
|
|
|
@@ -91,9 +118,6 @@ class SQLAlchemy:
|
|
|
91
118
|
Base class for creating database models
|
|
92
119
|
User writes: class User(db.Model):
|
|
93
120
|
'''
|
|
94
|
-
|
|
95
|
-
if not self._initialized:
|
|
96
|
-
raise DatabaseNotInitializedError('Database not Intialized, call db.init_app() first.')
|
|
97
121
|
|
|
98
122
|
return self._Model
|
|
99
123
|
|
|
@@ -136,8 +160,8 @@ class SQLAlchemy:
|
|
|
136
160
|
if not self._initialized:
|
|
137
161
|
raise DatabaseNotInitializedError('Database not Intialized, call db.init_app() first.')
|
|
138
162
|
|
|
139
|
-
session = self.
|
|
163
|
+
session = self.session()
|
|
140
164
|
try:
|
|
141
165
|
yield session # Give session to the route
|
|
142
166
|
finally:
|
|
143
|
-
session.
|
|
167
|
+
self.session.remove() #proper cleanup for scoped sessions
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fastapi-sqlalchemy-ease
|
|
3
|
+
Version: 0.1.5
|
|
4
|
+
Summary: A reusable SQLAlchemy extension for FastAPI
|
|
5
|
+
Requires-Python: >=3.8
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: sqlalchemy>=2.0.0
|
|
9
|
+
Dynamic: description
|
|
10
|
+
Dynamic: description-content-type
|
|
11
|
+
Dynamic: license-file
|
|
12
|
+
Dynamic: requires-dist
|
|
13
|
+
Dynamic: requires-python
|
|
14
|
+
Dynamic: summary
|
|
15
|
+
|
|
16
|
+
# fastapi-sqlalchemy-ease
|
|
17
|
+
|
|
18
|
+
fastapi-sqlalchemy-ease is a singleton-based SQLAlchemy extension for FastAPI. It provides a centralized interface for database initialization, model declaration, and session management, inspired by the simplicity of Flask-SQLAlchemy.
|
|
19
|
+
|
|
20
|
+
## ◽ Key Features
|
|
21
|
+
|
|
22
|
+
- Singleton Design: Ensures a single database instance across your entire FastAPI application.
|
|
23
|
+
|
|
24
|
+
- Consolidated API: Access all SQLAlchemy types (Integer, String, ForeignKey, etc.) directly from the db object.
|
|
25
|
+
|
|
26
|
+
- Auto-Cleanup: Includes a generator-based session handler designed for FastAPI's Depends to ensure sessions are always closed.
|
|
27
|
+
|
|
28
|
+
- Built-in Lifecycle Management: Simple methods for create_all() and drop_all().
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## ◽ Installation
|
|
32
|
+
|
|
33
|
+
pip install fastapi-sqlalchemy-ease
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
## ◽ Usage Guide
|
|
38
|
+
|
|
39
|
+
### 1. Basic setup
|
|
40
|
+
Initialize your database instance in a centralized file (e.g. database.py).
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
from fastapi_sqlalchemy_ease import SQLAlchemy
|
|
44
|
+
|
|
45
|
+
'''Create the singleton instance'''
|
|
46
|
+
db = SQLAlchemy()
|
|
47
|
+
|
|
48
|
+
'''Initialize with your URI'''
|
|
49
|
+
DATABASE_URI = "sqlite:///./test.db"
|
|
50
|
+
|
|
51
|
+
'''Use connect_args={"check_same_thread": False} for SQLite'''
|
|
52
|
+
db.init_app(DATABASE_URI, connect_args={"check_same_thread": False})
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
### 2. Defining Models
|
|
57
|
+
No need to import types from SQLAlchemy; use the db instance directly.
|
|
58
|
+
|
|
59
|
+
class User(db.Model):
|
|
60
|
+
__tablename__ = "users"
|
|
61
|
+
|
|
62
|
+
id = db.Column(db.Integer, primary_key=True)
|
|
63
|
+
username = db.Column(db.String, unique=True, nullable=False)
|
|
64
|
+
created_at = db.Column(db.DateTime)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### 3. Creating Tables
|
|
69
|
+
You can trigger table creation easily.
|
|
70
|
+
|
|
71
|
+
db.create_all()
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
### 3. Database Operations in Routes
|
|
76
|
+
Use db.Session with FastAPI's Depends to get a clean session for every request.
|
|
77
|
+
|
|
78
|
+
from fastapi import FastAPI, Depends
|
|
79
|
+
from .. import db
|
|
80
|
+
|
|
81
|
+
app = FastAPI()
|
|
82
|
+
|
|
83
|
+
@app.get("/users")
|
|
84
|
+
def read_users(session: Session = Depends(db.Session)):
|
|
85
|
+
users = session.query(User).all()
|
|
86
|
+
return users
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
## ◽ Available Attributes
|
|
91
|
+
Your db instance provides easy access to standard SQLAlchemy types and constraints:
|
|
92
|
+
|
|
93
|
+
Category - Available Attributes
|
|
94
|
+
|
|
95
|
+
Data Types - String, Integer, Float, Boolean, Text, Date, DateTime, JSON, Numeric
|
|
96
|
+
Constraints - ForeignKey, UniqueConstraint, CheckConstraint, Index
|
|
97
|
+
ORM - relationship, Table, Column
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
## ◽ Error Handling
|
|
102
|
+
The library includes a DatabaseNotInitializedError. If you attempt to access db.Model, db.Session, or lifecycle methods before calling db.init_app(), a clear exception will be raised to help you debug quickly.
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
## 📄 License
|
|
107
|
+
Distributed under the MIT License.
|
|
108
|
+
|
|
109
|
+
--
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
fastapi_sqlalchemy_ease/__init__.py,sha256=bJALhusgwO6bgq3Y1y9FwT1TfSiRYO4zh10SlFK-D8s,303
|
|
2
|
+
fastapi_sqlalchemy_ease/core.py,sha256=Uc6rbLLZ6gTCetkzX0a9VqVvafJQm5eyTOw_02dIM1g,4470
|
|
3
|
+
fastapi_sqlalchemy_ease/exceptions.py,sha256=6YU6mJvOGXC9D0mPH99GjMWpj21NA5jD8II7DWEcHaA,222
|
|
4
|
+
fastapi_sqlalchemy_ease-0.1.5.dist-info/licenses/LICENSE,sha256=jVnW2ZK4LFNHmDZE-xj0EyVpbHVMpwO7FcTk_We8qrA,1068
|
|
5
|
+
fastapi_sqlalchemy_ease-0.1.5.dist-info/METADATA,sha256=2XnxNnRUxd7Ge_TKeDGCM7c_Yhs7l1N6SvJU4kFNceU,3144
|
|
6
|
+
fastapi_sqlalchemy_ease-0.1.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
7
|
+
fastapi_sqlalchemy_ease-0.1.5.dist-info/top_level.txt,sha256=Y9kRilavMJot8bwOZymZ0cRjiBNIzsVqx9EwvXGiq-8,24
|
|
8
|
+
fastapi_sqlalchemy_ease-0.1.5.dist-info/RECORD,,
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: fastapi-sqlalchemy-ease
|
|
3
|
-
Version: 0.1.3
|
|
4
|
-
Summary: A reusable SQLAlchemy extension for FastAPI
|
|
5
|
-
Requires-Python: >=3.8
|
|
6
|
-
License-File: LICENSE
|
|
7
|
-
Requires-Dist: sqlalchemy>=2.0.0
|
|
8
|
-
Dynamic: license-file
|
|
9
|
-
Dynamic: requires-dist
|
|
10
|
-
Dynamic: requires-python
|
|
11
|
-
Dynamic: summary
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
fastapi_sqlalchemy_ease/__init__.py,sha256=rUUx_WPD1D830v7DpNSh_3_CsbJNMeJHHSBMF7GJLvs,303
|
|
2
|
-
fastapi_sqlalchemy_ease/core.py,sha256=nQSzioMp6TiD7yuKD7niImA2BSL2PQLCKnCzk0eFWrA,3920
|
|
3
|
-
fastapi_sqlalchemy_ease/exceptions.py,sha256=6YU6mJvOGXC9D0mPH99GjMWpj21NA5jD8II7DWEcHaA,222
|
|
4
|
-
fastapi_sqlalchemy_ease-0.1.3.dist-info/licenses/LICENSE,sha256=jVnW2ZK4LFNHmDZE-xj0EyVpbHVMpwO7FcTk_We8qrA,1068
|
|
5
|
-
fastapi_sqlalchemy_ease-0.1.3.dist-info/METADATA,sha256=LE0IDLlbyKIsWgRhyw5Jpo8p4HoKOwlif_AVJ8_zPkw,285
|
|
6
|
-
fastapi_sqlalchemy_ease-0.1.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
7
|
-
fastapi_sqlalchemy_ease-0.1.3.dist-info/top_level.txt,sha256=Y9kRilavMJot8bwOZymZ0cRjiBNIzsVqx9EwvXGiq-8,24
|
|
8
|
-
fastapi_sqlalchemy_ease-0.1.3.dist-info/RECORD,,
|
|
File without changes
|
{fastapi_sqlalchemy_ease-0.1.3.dist-info → fastapi_sqlalchemy_ease-0.1.5.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{fastapi_sqlalchemy_ease-0.1.3.dist-info → fastapi_sqlalchemy_ease-0.1.5.dist-info}/top_level.txt
RENAMED
|
File without changes
|