Skip to content

Instantly share code, notes, and snippets.

@Greyvend
Created February 7, 2021 15:59
Show Gist options
  • Save Greyvend/b56baa53b96e5bbfa7b650c3e6b69d40 to your computer and use it in GitHub Desktop.
Save Greyvend/b56baa53b96e5bbfa7b650c3e6b69d40 to your computer and use it in GitHub Desktop.
Repository pattern implementation in Python
"""
This is Python implementation of Repository pattern for accessing Data model
in an Object Oriented manner, simulating collection interface and abstracting
persistence operations.
The Repository also has Factory method for dealing with different Databases. Another
approach is to add direct engine string ingestion to the Repository __init__ method.
"""
from abc import ABC
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
class RepositoryInterface(ABC):
def create(self, *args, **kwargs):
raise NotImplemented()
def list(self):
raise NotImplemented()
def get(self, id_):
raise NotImplemented()
def update(self, **fields):
raise NotImplemented()
def delete(self, id_):
raise NotImplemented()
class Repository(RepositoryInterface):
def __init__(self, model_cls):
engine = self.engine_factory()
self.session = Session(bind=engine)
self.model_cls = model_cls
def create(self, *args, **kwargs):
obj = self.model_cls(*args, **kwargs)
self.session.add(obj)
self.session.commit()
def list(self):
return list(self.session.query(self.model_cls).order_by(self.model_cls.id))
def get(self, id_):
return self.session.query(self.model_cls).get(id_)
def update(self, id_, **fields):
obj = self.get(id_)
for field, value in fields.items():
obj.__setattr__(field, value)
self.session.commit()
def delete(self, id_):
self.session.delete(self.get(id_))
def engine_factory(self):
# Factory method
raise NotImplemented()
class SQLiteRepository(Repository):
def engine_factory(self):
return create_engine('sqlite:///:memory:', echo=True)
class MySQLRepository(Repository):
def engine_factory(self):
return create_engine('mysql://scott:tiger@localhost/foo', echo=True)
class PostgresRepository(Repository):
def engine_factory(self):
return create_engine('postgresql://scott:tiger@localhost/mydatabase', echo=True)
@BlasLajarin
Copy link

BlasLajarin commented May 7, 2022

thanks a lot!

missing self.session.commit() here (line 56):

def delete(self, id_):
        self.session.delete(self.get(id_)) 
        self.session.commit()

@lohxx
Copy link

lohxx commented Aug 25, 2022

Thanks, these abstractions are good.

@alvarobasso
Copy link

Nice, is a good implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment