1

I have a repository in my FastAPI app which is responsible for SQLAlchemy queries;

class MessageRepository:
    def __init__(self, db:Session):
        self.db = db
    
    def get_inbox_messages(self, user):
        return self.db.query(models.Messages).filter(models.Messages.receiver == user).all()


    def get_outbox_meesages(self, user):
        return self.db.query(models.Messages).filter(models.Messages.sender == user).all()


    def get_inbox_unseen_meesages(self, user):
        return self.db.query(models.Messages).\
            filter(models.Messages.receiver == user, models.Messages.seen == False).all()

Is it possible to combine these three functions in one? and how?

Alex
  • 17
  • 3

1 Answers1

1

You can have a function which receives variadic keyword arguments and uses them as in the filter method.

If there is no keyword argument passed, then the query is a simple SELECT ... FROM ....

And you can keep your current functions as aliases.

class MessageRepository:
    def __init__(self, db:Session):
        self.db = db

    def get_messages(self, **filters):
        return self.db.query(models.Messages).filter(
            getattr(models.Messages, attr) == value for attr, value in filters.items()
        ).all()
    
    def get_inbox_messages(self, user):
        return self.get_messages({"receiver": user})

    def get_outbox_meesages(self, user):
        return self.get_messages({"sender": user})

    def get_inbox_unseen_meesages(self, user):
        return self.get_messages({"receiver": user, "seen": False})
ljmc
  • 4,830
  • 2
  • 7
  • 26
  • Is this really different from the answers in the suggested duplicate? – snakecharmerb Feb 02 '23 at 07:25
  • @snakecharmerb While I did miss your comment and this is a fuller response than the one in the duplicate, if you vote to close as duplicate I'll support it. – ljmc Feb 02 '23 at 09:44
  • Thank you Guys! I tried dynamic filtering but I received "TypeeError" as, ...MessageRepository.get_messages() takes 1 positional argument but 2 were given – Alex Feb 03 '23 at 12:29
  • Ah, yes my bad, I stopped positional arguments with `/`, will edit. – ljmc Feb 03 '23 at 13:12