Lightweight library for providing filtering mechanism for your APIs using SQLAlchemy

Overview

example workflow example workflow codecov

sqlalchemy-filters-plus is a light-weight extendable library for filtering queries with sqlalchemy.

Install

pip install sqlalchemy-fitlers-plus

Usage

This library provides an easy way to filter your SQLAlchemy queries, which can for example be used by your users as a filtering mechanism for your exposed models via an API.

Let's define an example of models that will be used as a base query.

from sqlalchemy import Column, Date, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref

Base = declarative_base()


class User(Base):
    id = Column(Integer, primary_key=True)
    email = Column(String)
    age = Column(Integer)
    birth_date = Column(Date, nullable=False)


class Article(Base):
    id = Column(Integer, primary_key=True)
    title = Column(String)
    user_id = Column(Integer, ForeignKey(User.id), nullable=False)
    user = relationship(
        User,
        uselist=False,
        lazy="select",
        backref=backref("articles", uselist=True, lazy="select"),
    )

Define your first filter

Let's then define our first Filter class for the Article model

from sqlalchemy_filters import Filter, StringField
from sqlalchemy_filters.operators import ContainsOperator


class ArticleFilter(Filter):
    title = StringField(lookup_operator=ContainsOperator)
    email = StringField(field_name="user.email")

    class Meta:
        model = Article
        session = my_sqlalchemy_session

The example above defines a new filter class attached to the Article model, we declared two fields to filter with, title with the lookup_operator ContainsOperator and an email field which points to the user's email, hence the field_name="user.email" without any lookup_operator (default value is EqualsOperator) that will be used to filter with on the database level. We will see other operators that can also be used.

To apply the filter class, we instantiate it and pass it the data(as a dictionary) to filter with.

my_filter = ArticleFilter(data={"email": "[email protected]", "title": "python"})
query = my_filter.apply()  # query is a SQLAlchemy Query object

Please read the full documentation here https://sqlalchemy-filters-plus.readthedocs.io/

You might also like...
flask-apispec MIT flask-apispec (🥉24 · ⭐ 520) - Build and document REST APIs with Flask and apispec. MIT

flask-apispec flask-apispec is a lightweight tool for building REST APIs in Flask. flask-apispec uses webargs for request parsing, marshmallow for res

Flask + marshmallow for beautiful APIs

Flask-Marshmallow Flask + marshmallow for beautiful APIs Flask-Marshmallow is a thin integration layer for Flask (a Python web framework) and marshmal

A template for Flask APIs.
A template for Flask APIs.

FlaskAPITempate A template for a Flask API. Why tho? I just wanted an easy way to create a Flask API. How to setup First, use the template. You can do

Seamlessly serve your static assets of your Flask app from Amazon S3

flask-s3 Seamlessly serve the static assets of your Flask app from Amazon S3. Maintainers Flask-S3 is maintained by @e-dard, @eriktaubeneck and @SunDw

Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application.

Flask-Bcrypt Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application. Due to the recent increased prevelance of

A basic JSON-RPC implementation for your Flask-powered sites
A basic JSON-RPC implementation for your Flask-powered sites

Flask JSON-RPC A basic JSON-RPC implementation for your Flask-powered sites. Some reasons you might want to use: Simple, powerful, flexible and python

:rocket: Generate a Postman collection from your Flask application
:rocket: Generate a Postman collection from your Flask application

flask2postman A tool that creates a Postman collection from a Flask application. Install $ pip install flask2postman Example Let's say that you have a

Adds GraphQL support to your Flask application.

Flask-GraphQL Adds GraphQL support to your Flask application. Usage Just use the GraphQLView view from flask_graphql from flask import Flask from flas

A basic JSON-RPC implementation for your Flask-powered sites
A basic JSON-RPC implementation for your Flask-powered sites

Flask JSON-RPC A basic JSON-RPC implementation for your Flask-powered sites. Some reasons you might want to use: Simple, powerful, flexible and python

Comments
  • ArgumentError on pre-joined query

    ArgumentError on pre-joined query

    I'm not totally sure what's causing this so apologies for the somewhat vague issue. Hopefully you'll have a better idea!

    I have a query with a couple of joins on it already and when I attempt to filter it, I'm getting the following exception:

      File "/usr/local/lib/python3.9/site-packages/sqlalchemy_filters/filters.py", line 563, in apply
        query = self._apply_join(query)
      File "/usr/local/lib/python3.9/site-packages/sqlalchemy_filters/filters.py", line 364, in _apply_join
        if is_already_joined(query, join[0]):
      File "/usr/local/lib/python3.9/site-packages/sqlalchemy_filters/utils.py", line 37, in is_already_joined
        return join_table in [_[0] for _ in query._legacy_setup_joins]
      File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/operators.py", line 366, in __eq__
        return self.operate(eq, other)
      File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 317, in operate
        return op(self.comparator, *other, **kwargs)
      File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/relationships.py", line 1302, in __eq__
        self.property._optimized_compare(
      File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/relationships.py", line 1690, in _optimized_compare
        raise sa_exc.ArgumentError(
    sqlalchemy.exc.ArgumentError: Mapped instance expected for relationship comparison to object.   Classes, queries and other SQL elements are not accepted in this context; for comparison with a subquery, use DataSource.owner.has(**criteria).
    
    opened by TWeatherston 3
  • Using filter on query with a join creates a duplicate join

    Using filter on query with a join creates a duplicate join

    I have these two related models eg:

    class Organisation(Base):
        __tablename__ = "organisations"
        id = Column(INTEGER, primary_key=True)
        name = Column(VARCHAR(64))
    
    
    class User(Base):
        __tablename__ = "users"
        id = Column(INTEGER, primary_key=True)
        name = Column(VARCHAR(64))
        email = Column(VARCHAR(64))
        organisation_id = Column(Integer, ForeignKey("organisations.id"))
        organisation = relationship("Organisation")
    

    And then a filter for filtering users:

    class UserFilter(Filter):
        name = Field()
        email = Field(lookup_operator=ContainsOperator)
        organisation = Field(field_name="organisation.name")
    
        class Meta:
            model = User
    

    If I then create a query with a join and attempt to apply the filter to the query:

    query = db_session.query(User).join(Organisation)
    my_filter = UserFilter(data={"organisation": "test_org"}, query=query)
    query = my_filter.apply()
    print(str(query))
    

    It creates this second joining of the organisations table:

    SELECT 
        users.id AS users_id, 
        users.name AS users_name, 
        users.email AS users_email, 
        users.organisation_id AS users_organisation_id
    FROM users 
        JOIN organisations ON organisations.id = users.organisation_id
        JOIN organisations ON organisations.id = users.organisation_id
    WHERE organisations.name = ?
    
    opened by TWeatherston 1
  • Ordering by UnaryExpression raises TypeError

    Ordering by UnaryExpression raises TypeError

    Hey,

    Really love the package, great work! :+1:

    I've just been having some difficulty using the order_by with a UnaryExpression. Example from the docs:

    MyFilter(data={"order_by": User.first_name.asc()})
    

    This results in:

    TypeError: Boolean value of this clause is not defined

    It seems that this is the offending line. Would it be possible to get this changed to something like this?

    order_by = self.data.get("order_by", self._order_by)
    

    Here's a minimal working example that I was using to test this:

    from sqlalchemy import Column, VARCHAR, INTEGER, create_engine
    from sqlalchemy.orm import declarative_base, Session
    from sqlalchemy_filters import Filter, Field
    
    
    Base = declarative_base()
    
    
    class User(Base):
        __tablename__ = "users"
        id = Column(INTEGER, primary_key=True)
        name = Column(VARCHAR(64))
        email = Column(VARCHAR(64))
    
    
    class UserFilter(Filter):
        name = Field()
    
        class Meta:
            model = User
    
    
    engine = create_engine("sqlite://")
    with Session(engine) as session:
        query = session.query(User)
        my_filter = UserFilter(data={"order_by": User.name.desc()}, query=query)
        query = my_filter.apply()
    

    Thanks!

    opened by TWeatherston 1
  • Doesn't seem to apply the specific filter

    Doesn't seem to apply the specific filter

    Hi, Using your library, and this seemed to be not filtering with address_id and business_id base_filter = ScreeningHistoryFilter(data={"address_id":f"{address_id}", "business_id":f"{business_id}", "page":pagination_params.page_index, "page_size": pagination_params.page_size, "order_by": sort_params.sort_fields}, session= self.db)

    Below is the filter class: `class ScreeningHistoryFilter(Filter): address_id: Field() business_id: Field() # start_range: DateTimeField(field_name ='create_tz', lookup_operator = GTEOperator) # end_range: DateTimeField(field_name ='create_tz', lookup_operator = LTEOperator)

    class Meta:
        model = V_Address_Screening_History`
    
    opened by jaballe 4
Releases(1.1.5)
Owner
Karami El Mehdi
Karami El Mehdi
Find and notify users in your Active Directory with weak passwords

Crack-O-Matic Find and notify users in your Active Directory with weak passwords. Features: Linux-based Flask-based web app Hashcat or John cracker Au

Adrian Vollmer 92 Dec 31, 2022
Lightweight library for providing filtering mechanism for your APIs using SQLAlchemy

sqlalchemy-filters-plus is a light-weight extendable library for filtering queries with sqlalchemy. Install pip install sqlalchemy-fitlers-plus Usage

Karami El Mehdi 38 Oct 05, 2022
Adds GraphQL support to your Flask application.

Flask-GraphQL Adds GraphQL support to your Flask application. Usage Just use the GraphQLView view from flask_graphql from flask import Flask from flas

GraphQL Python 1.3k Jan 03, 2023
Learn python and flask,just a tony blog system

flaskblog Learn python and flask,just a tony blog system based on flask and mysql It is similar to cleanblog, a blog system based on flask and mongoen

shin 174 Dec 01, 2022
Full Stack Web Development with Flask.

Discover Flask Full Stack Web Development with Flask. http://discoverflask.com Flask is a micro web framework powered by Python. Its API is fairly sma

Real Python 4.4k Jan 06, 2023
Alexa Skills Kit for Python

Program the Amazon Echo with Python Flask-Ask is a Flask extension that makes building Alexa skills for the Amazon Echo easier and much more fun. Flas

John Wheeler 1.9k Dec 30, 2022
Pagination support for flask

flask-paginate Pagination support for flask framework (study from will_paginate). It supports several css frameworks. It requires Python2.6+ as string

Lix Xu 264 Nov 07, 2022
A flask template with Bootstrap 4, asset bundling+minification with webpack, starter templates, and registration/authentication. For use with cookiecutter.

cookiecutter-flask A Flask template for cookiecutter. (Supports Python ≥ 3.6) See this repo for an example project generated from the most recent vers

4.3k Dec 29, 2022
A flask app that turn image into ASCII art

ASCII art A flask app that turn image into ASCII art. This app has been deployed to https://motmaytinh.herokuapp.com Getting Started These instruction

Trần Ngọc Quý 1 Jan 13, 2022
Socket.IO integration for Flask applications.

Flask-SocketIO Socket.IO integration for Flask applications. Installation You can install this package as usual with pip: pip install flask-socketio

Miguel Grinberg 4.9k Jan 02, 2023
Full text search for flask.

flask-msearch Installation To install flask-msearch: pip install flask-msearch # when MSEARCH_BACKEND = "whoosh" pip install whoosh blinker # when MSE

honmaple 197 Dec 29, 2022
docker-compose uWSGI nginx flask

docker-compose uWSGI nginx flask Note that this was tested on CentOS 7 Usage sudo yum install docker

Abdolkarim Saeedi 3 Sep 11, 2022
Track requests to your Flask website with Matomo

Flask-Matomo Flask-Matomo is a library which lets you track the requests of your Flask website using Matomo (Piwik). Installation pip install flask-ma

Lucas Hild 13 Jul 14, 2022
REST API built using flask framework that used for managing bookmarks by individual users.

Bookmarks REST API REST API built using flask framework that used for managing bookmarks by individual users. API Consumers Note This app is built usi

Venkatesh Tantravahi 1 Dec 27, 2021
Mixer -- Is a fixtures replacement. Supported Django, Flask, SqlAlchemy and custom python objects.

The Mixer is a helper to generate instances of Django or SQLAlchemy models. It's useful for testing and fixture replacement. Fast and convenient test-

Kirill Klenov 870 Jan 08, 2023
flask-apispec MIT flask-apispec (🥉24 · ⭐ 520) - Build and document REST APIs with Flask and apispec. MIT

flask-apispec flask-apispec is a lightweight tool for building REST APIs in Flask. flask-apispec uses webargs for request parsing, marshmallow for res

Joshua Carp 617 Dec 30, 2022
Boilerplate template formwork for a Python Flask application with Mysql,Build dynamic websites rapidly.

Overview English | 简体中文 How to Build dynamic web rapidly? We choose Formwork-Flask. Formwork is a highly packaged Flask Demo. It's intergrates various

aswallz 81 May 16, 2022
retorna informações de pessoas que não existem

random-person-api API que entrega dados aleatórios sobre pessoas que (provavelmente) não existem. Como usar? Copie o link abaixo https://random-person

Miguel 3 Aug 09, 2022
Example Flask application illustrating some of my common practices

Overholt Overholt is an example Flask application illustrating some of my common practices Development Environment At the bare minimum you'll need the

Matt Wright 1.6k Dec 15, 2022
Pf-flask-rest-com - Flask REST API Common Implementation by Problem Fighter Library

In the name of God, the Most Gracious, the Most Merciful. PF-Flask-Rest-Com Docu

Problem Fighter 3 Jan 15, 2022