Skip to content

Commit

Permalink
Update testing versions (#94)
Browse files Browse the repository at this point in the history
Update testing versions
  • Loading branch information
M1ha-Shvn authored Oct 24, 2023
1 parent 23db82c commit e5f74a5
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 100 deletions.
71 changes: 15 additions & 56 deletions .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,68 +11,27 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10"]
postgres-version: ["9.4", "9.5", "9.6", "10", "11", "12", "13"]
django-version: ["1.8", "1.9", "1.10", "1.11", "2.0", "2.1", "2.2", "3.0", "3.1", "3.2", "4.0"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
postgres-version: ["9.6", "10", "11", "12", "13", "14", "15"]
django-version: ["3.1", "3.2", "4.0", "4.1", "4.2"]
exclude:
# Django 4.0+ doesn't support python 3.6, 3.7
- python-version: "3.7"
django-version: "4.0"

# Django 3.0+ doesn't support PostgreSQL 9.4
- django-version: "3.0"
postgres-version: "9.4"
- django-version: "3.1"
postgres-version: "9.4"
- django-version: "3.2"
postgres-version: "9.4"
- django-version: "4.0"
postgres-version: "9.4"

# Django 3.2+ doesn't support PostgreSQL 9.5
- django-version: "3.2"
postgres-version: "9.5"
- django-version: "4.0"
postgres-version: "9.5"

# Django 4.0+ doesn't support PostgreSQL 9.6
- django-version: "4.0"
postgres-version: "9.6"
- django-version: "4.1"
postgres-version: "9.6"
- django-version: "4.2"
postgres-version: "9.6"

# python 3.6+ has deprecated issue with django before 1.11
# https://stackoverflow.com/questions/41343263/provide-classcell-example-for-python-3-6-metaclass\
- python-version: "3.7"
django-version: "1.8"
- python-version: "3.7"
django-version: "1.9"
- python-version: "3.7"
django-version: "1.10"
- python-version: "3.8"
django-version: "1.8"
- python-version: "3.8"
django-version: "1.9"
- python-version: "3.8"
django-version: "1.10"
- python-version: "3.9"
django-version: "1.8"
- python-version: "3.9"
django-version: "1.9"
- python-version: "3.9"
django-version: "1.10"
- python-version: "3.10"
django-version: "1.8"
- python-version: "3.10"
django-version: "1.9"
- python-version: "3.10"
django-version: "1.10"

# Django before 2.1 is not compatible with python 3.10
# as it uses collections.Iterator
- python-version: "3.10"
django-version: "2.0"
- python-version: "3.10"
django-version: "1.11"
# Django 4.1+ doesn't support PostgreSQL 10
- django-version: "4.1"
postgres-version: "10"
- django-version: "4.2"
postgres-version: "10"

# Django 4.2+ doesn't support PostgreSQL 11
- django-version: "4.2"
postgres-version: "11"

services:
postgres:
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ services:
build:
context: .
args:
- PYTHON_IMAGE_TAG=latest
- PYTHON_IMAGE_TAG=3.11
volumes:
- ./.docker/wait-for-it.sh:/bin/wait-for-it.sh
command: ["/bin/bash", "/bin/wait-for-it.sh", "postgres_db:5432", "-s", "-t", "0", "--", "python3", "runtests.py"]
Expand Down
5 changes: 1 addition & 4 deletions requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
django>=1.7

# FIXME On later versions I get strange error 'database connection isn't set to UTC'
psycopg2<=2.8.6

psycopg2
pytz; python_version < '3.3'
typing; python_version < '3.5'

Expand Down
26 changes: 24 additions & 2 deletions src/django_pg_bulk_update/compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@

import django
from django.db import connection, connections, models, migrations
from django.db.models import Model, Field, BigIntegerField, IntegerField

from django.db.models import Model, Field, BigIntegerField, IntegerField, Q, Value, BooleanField

try:
# For django 3.2+
Expand Down Expand Up @@ -40,6 +39,14 @@
tz_utc = pytz.utc


try:
from django.core.exceptions import FullResultSet
except ImportError:
# For django before 4.2
class FullResultSet(Exception):
pass


def zip_longest(*args, **kwargs):
"""
https://docs.python.org/3.5/library/itertools.html#itertools.zip_longest
Expand Down Expand Up @@ -215,6 +222,21 @@ def get_model_fields(model, concrete=False): # type: (Type[Model], Optional[boo
return res


def get_empty_q_object() -> Q:
"""
Generates Q-Object, which leads to empty QuerySet.
See https://stackoverflow.com/questions/35893867/always-false-q-object
"""
import django
if django.VERSION >= (3,):
return Q(Value(False, output_field=BooleanField()))

# Django before 3.0 doesn't work with not binary conditions and expects field name to be always present.
# It raises TypeError: cannot unpack non-iterable Value object.
# This condition raises EmptyResultSet while forming query and doesn't even execute it
return Q(pk__in=[])


# Postgres 9.4 has JSONB support, but doesn't support concat operator (||)
# So I've taken function to solve the problem from
# https://stackoverflow.com/questions/30101603/merging-concatenating-jsonb-columns-in-query
Expand Down
10 changes: 7 additions & 3 deletions src/django_pg_bulk_update/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
from django.db.models.sql import UpdateQuery
from django.db.models.sql.where import WhereNode

from tests.compatibility import get_empty_q_object
from .compatibility import get_postgres_version, get_model_fields, returning_available, string_types, Iterable
from .compatibility import get_postgres_version, get_model_fields, returning_available, string_types,\
get_empty_q_object, Iterable, FullResultSet
from .set_functions import AbstractSetFunction, NowSetFunction
from .types import TOperators, TFieldNames, TUpdateValues, TSetFunctions, TOperatorsValid, TUpdateValuesValid, \
TSetFunctionsValid, TDatabase, FieldDescriptor, AbstractFieldFormatter
Expand Down Expand Up @@ -271,7 +271,11 @@ def _validate_where(model, where, using):
query = UpdateQuery(model)
conn = connections[using] if using else connection
compiler = query.get_compiler(connection=conn)
sql, params = where.as_sql(compiler, conn)

try:
sql, params = where.as_sql(compiler, conn)
except FullResultSet:
return '', tuple()

# I change table name to "t" inside queries
if sql:
Expand Down
34 changes: 0 additions & 34 deletions tests/compatibility.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
from datetime import date

from django.db.models import Value, Q, BooleanField
from django.template.backends import django
from django.utils.timezone import now
from django.utils.tree import Node

from django_pg_bulk_update.compatibility import get_postgres_version

Expand All @@ -19,34 +16,3 @@ def get_auto_now_date(key_is_unique=True): # type: (bool) -> date
:return: Date object
"""
return date.today() if not key_is_unique or get_postgres_version() < (9, 5) else now().date()


class EmptyQ(Q):
"""
Empty condition should return empty result
See https://stackoverflow.com/questions/35893867/always-false-q-object
"""
def __init__(self):
Node.__init__(self, children=[
("pk", Value(False, output_field=BooleanField()))
], connector=None, negated=False)

def __str__(self):
# Django before 3.0 raises 'TypeError: cannot unpack non-iterable Value object'
# when trying to insert Q(Value(False, output_field=BooleanField())) to
return 'FALSE'


def get_empty_q_object() -> Q:
"""
Generates Q-Object, which leads to empty QuerySet.
See https://stackoverflow.com/questions/35893867/always-false-q-object
"""
import django
if django.VERSION >= (3,):
return Q(Value(False, output_field=BooleanField()))

# Django before 3.0 doesn't work with not binary conditions and expects field name to be always present.
# It raises TypeError: cannot unpack non-iterable Value object.
# This condition raises EmptyResultSet while forming query and doesn't even execute it
return Q(pk__in=[])

0 comments on commit e5f74a5

Please sign in to comment.