fastapi-sqlalchemy-ease 0.1.4__tar.gz → 0.1.5__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-sqlalchemy-ease
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: A reusable SQLAlchemy extension for FastAPI
5
5
  Requires-Python: >=3.8
6
6
  Description-Content-Type: text/markdown
@@ -1,7 +1,7 @@
1
1
  from .core import SQLAlchemy
2
2
  from .exceptions import DatabaseError, DatabaseNotInitializedError
3
3
 
4
- __version__='0.1.4'
4
+ __version__='0.1.5'
5
5
 
6
6
  # when someone call: from fastapi_sqlalchemy import SQLAlchemy
7
7
  # only these things are available
@@ -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
- # Everything starts as None Until db.init_app() is called
51
- self.engine = None
52
- self._SessionLocal = None
53
- self._Model = None
54
- self._initialized = False
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, connect_args: Optional[dict]=None):
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 connect_args:
70
- engine_kwargs['connect_args'] = connect_args # sqlite need this
71
- else:
72
- engine_kwargs['pool_pre_ping'] = True # Keeps connection alive for PostgreSQL/MySQL
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
- # Model - base class, all our database models will inherit from
81
- self._Model = declarative_base()
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._SessionLocal()
163
+ session = self.session()
140
164
  try:
141
165
  yield session # Give session to the route
142
166
  finally:
143
- session.close() #always close after one requst
167
+ self.session.remove() #proper cleanup for scoped sessions
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-sqlalchemy-ease
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: A reusable SQLAlchemy extension for FastAPI
5
5
  Requires-Python: >=3.8
6
6
  Description-Content-Type: text/markdown
@@ -7,7 +7,7 @@ long_description = (this_directory / "README.md").read_text()
7
7
 
8
8
  setup(
9
9
  name='fastapi-sqlalchemy-ease',
10
- version='0.1.4',
10
+ version='0.1.5',
11
11
  description="A reusable SQLAlchemy extension for FastAPI",
12
12
  packages=find_packages(),
13
13
  long_description=long_description,