Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom queries breaks #371

Open
nikhilkalige opened this issue Nov 20, 2014 · 6 comments
Open

Custom queries breaks #371

nikhilkalige opened this issue Nov 20, 2014 · 6 comments
Labels

Comments

@nikhilkalige
Copy link

I am using custom queries like this with flask sqlalchemy

class SequenceUserTag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    ....

    # filter tags to include those created by user and user: 2
    @classmethod
    def query(cls):
        original_query = db.session.query(cls)
        if current_user.is_authenticated():
            condition = (cls.user_id == 2)
        else:
            condition = or_(cls.user_id == 2, cls.user_id == current_user.get_id())
        return original_query.filter(condition)

This works great when used with restless..

But if i try to access the filter method on the model in a view.. like SequenceUserTag.query.filter(SequenceUserTag.user_id == 3) i get a error AttributeError: 'function' object has no attribute 'filter'

But SequenceUserTag.query().filter() works..
So i wanted to know if there is way to make this works as expected something like Model.query.filter(), else this breaks the pattern somehow because models for which query is not overridden work like Model.query.filter() but Model.query().filter() breaks

I also tried the below

class User(db.Model):
   query_class = custom_query_class

class custom_query_class(Query):
    def __init__(self):
        super
    def __iter__(self):
        self = self.filter(condition)
        return Query.__iter__(self)

This fixes the problem i mentioned above but the result from the api gives me num_results as length prior to the filter applied.
So before filter length was 3 and after its 1. So the api gives the right data but wrong number for results

@jfinkels jfinkels added the bug label Nov 29, 2014
@jfinkels jfinkels assigned jfinkels and unassigned jfinkels Nov 29, 2014
@Romainpaulus
Copy link
Contributor

I had a similar problem but never thought about using query_class, that's a great idea. Have you thought about defining a __call__ method on your custom_query_class instead of __iter__? Flask-restless will call the query when it's possible.

@drmclean
Copy link

I've got around this by using the

db.session.query(models.<modelname>).filter_by

rather than

models.user.query.filter()

Does that help at all?

@nikhilkalige
Copy link
Author

@drmclean As you mentioned and as i have shown above, there are workarounds, but the problem i believe is with multiple people working on the same, you are kind using a different way of doing things. So its kind of a problem for my boss :)

@jfinkels
Copy link
Owner

Would it be better to have the user specify a decorator that marks the method as both a property and classmethod, as specified, for example, in this StackOverflow answer? This way, the user should be able to use MyModel.query without requiring an invocation of __call__.

@taion
Copy link

taion commented Feb 13, 2015

This could be another benefit of #406 - if you specify the custom query on the endpoint rather than on the model, you don't need to override Model.query and can preserve the standard Flask-SQLAlchemy semantics.

@nikhilkalige
Copy link
Author

@jfinkels Add classmethod works.. But i feel its kind of hackish way of doing it. Because it filters all queries that are made to that model. May be a better way would be to pass some kind of a query object during api creation. Just as maybe #406

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants