filters = (Project.usergroup==User.usergroup)
from pyramid.request import Requestfrom crudites.models.meta import Basefrom sqlalchemy.orm.session import Sessionfrom uuid import UUIDfrom typing import List, Tuple, Dictfrom crudites.services.id_service import IDService
class CRUDService: '''TODO: docstring'''
@staticmethod def create(cls: Base, s: Session) -> bool: unique_id, public_id = IDService.create_db_ids() cls.unique_id=unique_id cls.public_id=public_id s.add(cls) s.commit() return True
@staticmethod def read_by_pkid(cls: Base, s: Session, id: int) -> Base: q = s.query(cls).get(id) return q
@staticmethod def read_by_unique_id(cls: Base, s: Session, id: UUID) -> Base: q = s.query(cls).filter_by(unique_id=id).first() return q
@staticmethod def read_by_public_id(cls: Base, s: Session, id: str) -> Base: q = s.query(cls).filter_by(public_id=id).first() return q
@staticmethod def read_all(cls: Base, s: Session, filters: Tuple=None) -> List[Base]: if not filters: filters = (cls.is_deleted==False,) q = s.query(cls).filter(*filters).all() return q
@staticmethod def update(cls: Base, s: Session) -> bool: s.add(cls) s.commit() return True
@staticmethod def delete(cls: Base, s: Session)-> bool: cls.is_deleted=True s.add(cls) s.commit() return True
I have a generic CRUDService for my web app. It's a pattern that was loosely suggested to me by Mike a while back. I've probably not implemented it the way he intended, but it works pretty well in a pretty small amount of code.The main work, however, that needs to be done is in the read_all method. It needs to be able to handle different filters depending on which view is calling it. Which it can as it is now. But I want to fidget with the defaults a little. Basically, I almost never want to show objects that have been soft deleted. Only admin users/views should be able to fidget with things that we've "deleted". The way the method works now is that if I don't pass any filters in at all, it sets a filter to cls.is_deleted==False. But I'd like to be able to inspect incoming filters. Say the view looks at the resource context and determines that a view should only be allowed to see objects based on some ACL rule. I might create a filter for that view controller that looks likefilters = (Project.usergroup==User.usergroup)(defining the applicable usergroup for a given context is a separate service, but the relationship should be obvious, I think?)and then have the view query with CRUDService.read_all(Project, request.dbsession, filters). The way I've got it now, that would just replace the default filter, and I would have to add Project.is_deleted==False to the tuple of filters every time I call this. I would like to be able to inspect the filters that are passed into the read_all (which, honestly, I should rename and call it read_many) method and say, if there isn't any reference to the is_deleted column in the filters, then set that as false, otherwise, accept the value in the function parameter. But I find the filter's tuple values quite opaque. Once they are instantiated, they are class-specific, and I'm trying to get at a general way of understanding them. I'll note that this column is guaranteed to be present in the framework. I've modified the declarative base such that every object has the is_deleted. I appreciate any help you might be able to give. It's very likely I'm overthinking this like a numbskull and the answer is painfully obvious. Here's the service class:
--SQLAlchemy -The Python SQL Toolkit and Object Relational MapperTo post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description.---You received this message because you are subscribed to the Google Groups "sqlalchemy" group.To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+...@googlegroups.com.To post to this group, send email to sqlal...@googlegroups.com.Visit this group at https://groups.google.com/group/sqlalchemy.To view this discussion on the web visit https://groups.google.com/d/msgid/sqlalchemy/da43b503-1e7a-4a0e-bd32-619d96163c1c%40googlegroups.com.For more options, visit https://groups.google.com/d/optout.
To unsubscribe from this group and stop receiving emails from it, send an email to sqlal...@googlegroups.com.
FWIW, I found a better approach to a similar problem was to create a dict/object I used to log metadata about the query I wanted... then build the query or analyze it based on that metadata. All the information is in the sqlalchemy query, but the execution performance a development time was much faster when I stopped analyzing the query and just consulted the dict.
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to a topic in the Google Groups "sqlalchemy" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sqlalchemy/chGVkNwmKyQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to sqlalchemy+...@googlegroups.com.
To post to this group, send email to sqlal...@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
To view this discussion on the web visit https://groups.google.com/d/msgid/sqlalchemy/18bed722-c8c3-42a3-97de-a5f58987fdcf%40googlegroups.com.
That's very interesting, Jonathan. Could you show me a quick example of that approach? I'm not sure I *need* to do that, but I think I would learn about SQLAlchemy from such an example and trying to understand it.
query_metadata = {'requester': 'site-admin', # admin interface, user interface, user api, etc
'filters': {'Username=': 'foo', # just an internal notation
},
'query_data': {}, # information related to what is in the query as it is built }
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
http://www.sqlalchemy.org/
To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to a topic in the Google Groups "sqlalchemy" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sqlalchemy/chGVkNwmKyQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to sqlalchemy+...@googlegroups.com.
To post to this group, send email to sqlal...@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
To view this discussion on the web visit https://groups.google.com/d/msgid/sqlalchemy/39a4a326-c384-4c91-909a-40d9c3acb323%40googlegroups.com.