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

postgres test matrix #11

Merged
merged 5 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 28 additions & 18 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,24 @@ on:

permissions:
contents: read

jobs:
build:

test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11"]
django-version: ["4.0", "4.1", "4.2", "5.0", "5.1"]
exclude:
# Django 5.0+ requires Python 3.10+
- python-version: "3.9"
django-version: "5.0"
- python-version: "3.9"
django-version: "5.1"
max-parallel: 5

services:
postgres:
image: postgres
image: postgres:13
env:
POSTGRES_PASSWORD: postgres
options: >-
Expand All @@ -29,17 +38,18 @@ jobs:
- 5432:5432

steps:
- uses: actions/checkout@v3
- name: Set up Python 3.9
uses: actions/setup-python@v3
with:
python-version: "3.9"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r dev-requirements.txt
- name: Run tests
run: |
./check-lint.sh
python manage.py test -v 3 --no-input
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r dev-requirements.txt
pip install Django==${{ matrix.django-version }}
- name: Run tests
run: |
./check-lint.sh
python manage.py test -v 3 --no-input
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Django Querysets Single Query Fetch

Executes multiple querysets over a single db query and returns results which would have been returned in normal evaluation of querysets. This can help in critical paths to avoid network/connection-pooler latency if db cpu/mem are nowhere near exhaustion. Ideal use case is fetching multiple small and optimised independent querysets where above mentioned latencies can dominate total execution time.
Executes multiple querysets over a single db query and returns results which would have been returned in normal evaluation of querysets. This can help in critical paths to avoid network latency. Ideal use case is fetching multiple small and optimised independent querysets where above mentioned latencies can dominate total execution time.

Supports only Postgres as of now

Expand Down Expand Up @@ -45,12 +45,11 @@ Fetching count of queryset using `QuerysetCountWrapper` (since `queryset.count()
from django_querysets_single_query_fetch.service import QuerysetsSingleQueryFetch, QuerysetCountWrapper

querysets = [QuerysetCountWrapper(queryset=queryset1), queryset2, ...]
results = QuerysetsSingleQueryFetch(querysets=querysets)
results = QuerysetsSingleQueryFetch(querysets=querysets)

assert results == [queryset1.count(), list(queryset2), ...]
assert results == [queryset1.count(), list(queryset2), ...]
```


## Contribution suggestions

- Add tests (django version matrix, different types and parsing etc)
Expand All @@ -65,7 +64,6 @@ assert results == [queryset1.count(), list(queryset2), ...]
- MySQL support as an experiment
- "How it works" section/diagram?


## Notes

- Note parallelisation by postgres is not guaranteed, as it depends on lot of config params (max_parallel_workers_per_gather, min_parallel_table_scan_size, max_parallel_workers etc). Even without parallelisation, this can be faster than normal one-by-one evaluation of querysets due to reduced no of network trips.
2 changes: 1 addition & 1 deletion django_querysets_single_query_fetch/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def _get_fetch_count_compiler_from_queryset(
slightly modified copy paste from get_count and get_aggregation in django.db.models.sql.compiler
"""
obj = queryset.query.clone()
obj.add_annotation(Count("*"), alias="__count", is_summary=True)
obj.add_annotation(Count("*"), alias="__count")
added_aggregate_names = ["__count"]
existing_annotations = [
annotation
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
django==4
django==4.2
psycopg2==2.9.9
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

setuptools.setup(
name="django_querysets_single_query_fetch",
version="0.0.11",
version="0.0.12",
description="Execute multiple Django querysets in a single SQL query",
long_description="Utility which executes multiple Django querysets over a single network/query call and returns results which would have been returned in normal evaluation of querysets",
author="Nishant Singh",
author_email="[email protected]",
license="Apache Software License",
packages=["django_querysets_single_query_fetch"],
zip_safe=False,
install_requires=["django>3"],
install_requires=["django>=4.0,<5.2"],
python_requires=">=3.9",
include_package_data=True,
package_data={},
Expand Down
Loading