0

So we have a user table in our Flask App that has a is_active column to determine if the user is active or not. We want to use this column to be able to filter out inactive users from lists/dropdowns throughout the entire app.

I know I can just go and add a .filter(User.is_active == True) to every place we are using the user table but that doesn't seem like its the best options since developers could forget to add the filter as well as its not easily maintainable in the future.

I have tried googling for options and have tried a few different solutions that I have found but none of those seem like the best option. Here is what I have tried so far:

  1. Create an event listener (@event.listens_for(Query, "before_compile", retval=True)) to add a .filter() every time the user table is queried. This doesn't seem like the best option because this could have other implications that would cause unwanted results. We have instances in the app where we have a try/except on a .one() query on the User table that I wouldn't want this event listener to apply to.

  2. Pass in a query_cls into the session_maker() that has a method that will add the filter to the existing query. This seems better then just adding the .filter() to every query since its easier to maintain but still need to remember to add that method to each query.

So, I'm just wondering if there is another/better way of doing this so that its easy to maintain and doesn't require a developer to add when constructing a query that involves the user table. I feel like this request would be something that a lot of other places would want, so I'm flabbergasted that my google searching didn't yield something better.

Current package versions just in case:

sqlachemy - 1.3.13

flask - 1.1.2

This is my first post on stack overflow, so sorry if I didn't add enough information.

Thank you for your help in advance!

UPDATE:

Here is an example of the model:

class User(Auditable, Base):
    __tablename__ = "user"

    id = Column(INTEGER(11), primary_key=True)
    racf = Column(String(14), nullable=True, index=True)
    name = Column(String(128), nullable=True)
    email = Column(String(256), nullable=True, unique=True, index=True)
    job_title_id = Column(ForeignKey("job_title.id"), index=True)
    employee_status_id = Column(ForeignKey("employee_status.id"), index=True)
    is_exempt = Column(OurBoolean, server_default=text("0"))
    location_id = Column(ForeignKey("location.id"), index=True)
    business_unit_id = Column(ForeignKey("business_unit.id"), index=True)
    division_id = Column(ForeignKey("division.id"), index=True)
    department_id = Column(ForeignKey("department.id"), index=True)
    cost_center_id = Column(ForeignKey("cost_center.id"), index=True)
    is_active = Column(OurBoolean, server_default=text("0"))
    last_logon = Column(Date, index=True)

    job_title = relationship("JobTitle")
    employee_status = relationship("EmployeeStatus")
    location = relationship("Location")
    business_unit = relationship("BusinessUnit")
    division = relationship("Division")
    department = relationship("Department")
    cost_center = relationship("CostCenter")
    role_links = relationship(
        "UserRoleLink",
        back_populates="user",
    )

Here is an example query in current state:

user_table_data = (
        sqla_session.query(
            User.id,
            User.name,
            User.email,
            User.racf,
            JobTitle.description.label("job_title"),
            team_leader_table.name.label("manager"),
            Division.description.label("division"),
            CostCenter.description.label("cost_center"),
            EmployeeStatus.description.label("employee_status"),
            User.is_active,
        )
        .join(JobTitle, User.job_title_id == JobTitle.id, isouter=True)
        .join(Division, User.division_id == Division.id, isouter=True)
        .join(CostCenter, User.cost_center_id == CostCenter.id, isouter=True)
        .join(EmployeeStatus, User.employee_status_id == EmployeeStatus.id, isouter=True)
        .join(UserHierarchy, User.id == UserHierarchy.user_id, isouter=True)
        .join(team_leader_table, UserHierarchy.team_lead_id == team_leader_table.id, isouter=True)
    )

Creating a view seems redundant and would require some type of logic to maintain that view. Isn't that less than ideal?

Steve
  • 11
  • 3
  • It would help if you posted some Python code + your data model. But it seems to me that the best way is to create a view. Have a look here for suggestions: [How to create an SQL View with SQLAlchemy?](https://stackoverflow.com/q/9766940/6843158). Or simply create a function that includes the desired filtering criteria, so you don't have to repeat them across your code. – Kate Feb 04 '22 at 18:20
  • @Kate, added some code examples as requested. Also, I don't have the ability to create views in my mariadb database. It seems they have turned that ability off in my environment. – Steve Feb 04 '22 at 18:31

0 Answers0