Skip to main content

SQLAlchemy support for AIP-160 style filters

Project description

AIP-160 Filter Helper for SQLAlchemy

Installation

pip install sqlalchemy-aip160

Usage

from sqlalchemy import select
from sqlalchemy_aip160 import apply_filter, parse_filter, FilterBuilder

Basic filtering

query = select(MyModel)
filtered = apply_filter(query, MyModel, 'status = "active"')

Multiple conditions

filtered = apply_filter(query, MyModel, 'status = "active" AND priority > 3')

OR conditions

filtered = apply_filter(query, MyModel, 'status = "active" OR status = "pending"')

NOT operator

filtered = apply_filter(query, MyModel, 'NOT status = "inactive"')

Wildcard pattern matching

filtered = apply_filter(query, MyModel, 'name = "Widget*"')

Presence check (field is not null)

filtered = apply_filter(query, MyModel, 'category:*')

Complex nested expressions

filtered = apply_filter(
    query, MyModel,
    '(status = "active" OR status = "pending") AND priority >= 3'
)

Restrict filterable fields for security

filtered = apply_filter(
    query, MyModel, 'status = "active"',
    allowed_fields={"status", "priority"}  # Only these fields can be filtered
)

Field aliases

filtered = apply_filter(
    query, MyModel,
    'department = "Engineering"',
    field_aliases={"department": "department.name"}
)

Filter Inspection and Manipulation

parse_filter returns a structured FilterExpression that can be inspected, manipulated, serialized back to a string, or passed directly to apply_filter.

Inspect fields

expr = parse_filter('status = "active" AND priority > 3')
expr.get_fields()  # {'status', 'priority'}

Rename fields

expr = parse_filter('kind = "issue" AND source_id = "abc"')
expr.rename_field("kind", "kind_str")
str(expr)  # 'kind_str = "issue" AND source_id = "abc"'

Remove clauses

expr = parse_filter('status = "active" AND priority > 3')
expr.remove("priority")
str(expr)  # 'status = "active"'

Extract and replace clauses

expr = parse_filter('kind = "acc:issue" AND source_id = "abc"')
kind_clauses = expr.extract("kind")  # Removes and returns kind comparisons
replacement = FilterBuilder().add("kind", "=", "acc:meeting").build()
combined = expr & replacement
str(combined)  # 'source_id = "abc" AND kind = "acc:meeting"'

Combine expressions

user_filter = parse_filter('status = "active"')
server_filter = parse_filter('org_id = "org-123"')
combined = user_filter & server_filter  # AND
either = user_filter | server_filter    # OR
negated = ~user_filter                  # NOT

Build filters programmatically

f = FilterBuilder()
f.add("kind", "=", "issue").add("priority", ">", 3)
str(f)  # 'kind = "issue" AND priority > 3'

# Pass directly to apply_filter
query = apply_filter(select(MyModel), MyModel, f.build())

Pass FilterExpression to apply_filter

expr = parse_filter('status = "active"')
expr.rename_field("status", "state")
filtered = apply_filter(query, MyModel, expr)

Supported Features

Feature Example Notes
Equality status = "active" String, int, float, bool, UUID
Not equals status != "inactive"
Comparisons priority > 3, score <= 4.5 <, >, <=, >=
AND a = 1 AND b = 2 Explicit
Implicit AND a = 1 b = 2 Adjacent terms
OR a = 1 OR a = 2 Higher precedence than AND per AIP-160
NOT NOT status = "active" Also -status = "active"
Parentheses (a OR b) AND c
Wildcards name = "*.txt" Converted to SQL LIKE
Presence field:* Field is not null
Has value field:value Field equals value

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sqlalchemy_aip160-0.1.5.tar.gz (11.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sqlalchemy_aip160-0.1.5-py3-none-any.whl (13.8 kB view details)

Uploaded Python 3

File details

Details for the file sqlalchemy_aip160-0.1.5.tar.gz.

File metadata

  • Download URL: sqlalchemy_aip160-0.1.5.tar.gz
  • Upload date:
  • Size: 11.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for sqlalchemy_aip160-0.1.5.tar.gz
Algorithm Hash digest
SHA256 32bc18b2f06c833deedb9ec1d8d21bf1908f8bd715d0e3c12561860b90d21529
MD5 1595def3f3e77f34e039ff5c30b14a4d
BLAKE2b-256 288016a8b4dfcbfa67cd41a3c338d5ed6437cf67d0a7620753e68465d1b23905

See more details on using hashes here.

File details

Details for the file sqlalchemy_aip160-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: sqlalchemy_aip160-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 13.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for sqlalchemy_aip160-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 e3fde7e1fa83374cdb1759fa7411612700b1c7df6ce40b8274d40c5496ebd4e5
MD5 d91c48b9a453af035813932b072ee06c
BLAKE2b-256 fb060ba86bb95ce6e3c14b2af2bebfda1ce9dd504db03f9e5cdd5f9babf644c2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page