Skip to content

Instantly share code, notes, and snippets.

@hugochinchilla
Created March 24, 2017 18:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hugochinchilla/7150301219a756ba028a578dba27c776 to your computer and use it in GitHub Desktop.
Save hugochinchilla/7150301219a756ba028a578dba27c776 to your computer and use it in GitHub Desktop.
sqlalchemy model base class with object manager
from sqlalchemy.ext.declarative import DeclarativeMeta, declarative_base
# it's up to you how your session object is created
from .session import session as default_session
class Manager(object):
YIELD_CURSOR_SIZE = 100
def __init__(self, model, session=None):
self._model = model
self._session = session
@property
def model(self):
return self._model
@property
def session(self):
if self._session is None:
self._session = default_session
return self._session
@session.setter
def session(self, session):
self._session = session
def all(self):
return self._find().yield_per(self.YIELD_CURSOR_SIZE)
def get(self, *args, **kwargs):
return self._find(*args, **kwargs).scalar()
def require(self, *args, **kwargs):
obj = self.get(*args, **kwargs)
if obj is None:
raise self._model.DoesNotExist("The requested object does not exist") # noqa
return obj
def filter(self, *args, **kwargs):
return self._find(*args, **kwargs).yield_per(self.YIELD_CURSOR_SIZE)
def create(self, **kwargs):
new = self.model(**kwargs)
new.save()
return new
def save(self, instance):
self.session.add(instance)
self.session.flush()
def delete(self, instance):
self.session.delete(instance)
self.session.flush()
def select(self, *args):
if len(args) == 0:
args = [self.model]
return self.session.query(*args)
def _find(self, *args, **kwargs):
return self.select().filter(*args, **kwargs)
class ObjectDoesNotExist(Exception):
pass
class _ModelMeta(DeclarativeMeta):
def __new__(cls, clsname, superclasses, attrs):
new_class = super().__new__(cls, clsname, superclasses, attrs)
new_class.objects = Manager(new_class)
new_class.DoesNotExist = type(
'DoesNotExist',
(ObjectDoesNotExist,),
{'__module__': f'{new_class.__module__}.{clsname}'})
return new_class
class _BaseModel(object):
def save(self):
self.__class__.objects.save(self)
def delete(self):
self.__class__.objects.delete(self)
def __iter__(self):
return ((k, getattr(self, k)) for k in self.__table__.columns.keys())
Model = declarative_base(cls=_BaseModel, metaclass=_ModelMeta)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment