Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLAlchemy default filter

Tags:

I have a model with a field is_deleted, now I want all forms of query for this model to always filter by is_deleted=False in addition to whatever filtering arguments is passed to .filter and .filter_by.

In Django, I would normally override the manager and add my own filtering but I need help for SQLAlchemy.

UPDATE:

I ended-up doing the following:

class CustomQuery(Query):     def __new__(cls, *args, **kwargs):         if args and hasattr(args[0][0], "is_deleted"):             return Query(*args, **kwargs).filter_by(is_deleted=False)         else:             return object.__new__(cls) session = scoped_session(sessionmaker(query_cls=CustomQuery)) 

It works but if I have more fields later on I imagine I'll have to add more condition, there must be a way to do this on the model level.

like image 750
Marconi Avatar asked Apr 21 '12 20:04

Marconi


1 Answers

This is a very old question so I'm sure the OP solved their issue, but as it remains unanswered (in 2021) here's how we've approached applying a custom query class to all models:

  1. Define the custom query as above
class CustomQuery(Query): ... 
  1. Then set this query class as the query attribute on your base model class:
class BaseModel(Model):     __abstract__ = True     query_class = CustomQuery     ... 

Then any models implementing the BaseModel will obviously inherit this behaviour:

class MyModel(BaseModel):     __tablename__ = 'my_model'      ....  

Note, in our case not all of the tables follow the soft delete pattern (we don't care about the history of every single table). Here, you could implement a separate BaseModel that uses the default query class.

class ImmutableBaseModel(Model):     __abstract__ = True     query_class = CustomQuery     ...  class MutableBaseModel(Model):     __abstract__ = True  

If you find yourself here and you've not read it yet check out this excellent blog post from Miguel Grinberg on implementing the soft delete pattern and accompanying repo

 

like image 123
mdmjsh Avatar answered Sep 21 '22 12:09

mdmjsh