Opened 3 years ago

Closed 3 years ago

#27478 closed Cleanup/optimization (duplicate)

JSONB_AGG is not available in PostgreSQL 9.4

Reported by: Christian von Roques Owned by: nobody
Component: contrib.postgres Version: master
Severity: Normal Keywords: JsonAgg JSONB_AGG
Cc: Christian von Roques Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

django.contrib.postgres.aggregates.general.JsonAgg uses JSONB_AGG. The Django test-suite contains a test which fails due to JSONB_AGG being unavailable as shown below when run against PostgreSQL 9.4. The test is already marked as @skipUnlessDBFeature('has_jsonb_datatype'), but JSONB became available with PostgreSQL 9.4 and JSONB_AGG was added in PostgreSQL 9.5.
I currently see three possibilities:

  1. Add a new feature has_jsonb_agg and make the test @skipUnlessDBFeature('has_jsonb_agg')
  2. Add a new feature has_jsonb_agg and use JSON_AGG instead of JSONB_AGG when JSONB_AGG is unavailable.
  1. Have has_jsonb_datatype lie about it not being available in PostgreSQL 9.4.

I prefer and have implemented option 2 and really don't like option 3.

See my branch for my initial implementation. — Is there a cleaner way to achieve this besides redefining JsonAgg.as_sql?

ERROR: test_json_agg (postgres_tests.test_aggregates.TestGeneralAggregate)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/case.py", line 58, in testPartExecutor
    yield
  File "/usr/lib/python3.4/unittest/case.py", line 577, in run
    testMethod()
  File "/home/roques/tools/django/django/test/testcases.py", line 1113, in skip_wrapper
    return test_func(*args, **kwargs)
  File "/home/roques/tools/django/tests/postgres_tests/test_aggregates.py", line 122, in test_json_agg
    values = AggregateTestModel.objects.aggregate(jsonagg=JsonAgg('char_field'))
  File "/home/roques/tools/django/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/roques/tools/django/django/db/models/query.py", line 352, in aggregate
    return query.get_aggregation(self.db, kwargs.keys())
  File "/home/roques/tools/django/django/db/models/sql/query.py", line 461, in get_aggregation
    result = compiler.execute_sql(SINGLE)
  File "/home/roques/tools/django/django/db/models/sql/compiler.py", line 829, in execute_sql
    cursor.execute(sql, params)
  File "/home/roques/tools/django/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/home/roques/tools/django/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/home/roques/tools/django/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/home/roques/tools/django/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: function jsonb_agg(character varying) does not exist
LINE 1: SELECT JSONB_AGG("postgres_tests_aggregatetestmodel"."char_f...
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

Change History (2)

comment:1 Changed 3 years ago by Mads Jensen

You may need to refer this ticket in the commit #26327. contrib.postgres uses JSONB so I think option 2 needs a bit of work to cast to the normal JSON-field.

Last edited 3 years ago by Mads Jensen (previous) (diff)

comment:2 Changed 3 years ago by Tim Graham

Component: Uncategorizedcontrib.postgres
Resolution: duplicate
Status: newclosed

Since the new feature isn't released, we can reopen the original ticket to keep the discussion in one place. Thanks for the report.

Note: See TracTickets for help on using tickets.
Back to Top