Fixed #32179 -- Added JSONObject database function.

This commit is contained in:
Artur Beltsov 2020-11-08 12:52:34 +05:00 committed by Mariusz Felisiak
parent adb40d217e
commit 48b4bae983
8 changed files with 161 additions and 2 deletions

View file

@ -1,5 +1,7 @@
"""Database functions that do comparisons or type conversions."""
from django.db import NotSupportedError
from django.db.models.expressions import Func, Value
from django.db.models.fields.json import JSONField
from django.utils.regex_helper import _lazy_re_compile
@ -112,6 +114,46 @@ class Greatest(Func):
return super().as_sqlite(compiler, connection, function='MAX', **extra_context)
class JSONObject(Func):
function = 'JSON_OBJECT'
output_field = JSONField()
def __init__(self, **fields):
expressions = []
for key, value in fields.items():
expressions.extend((Value(key), value))
super().__init__(*expressions)
def as_sql(self, compiler, connection, **extra_context):
if not connection.features.has_json_object_function:
raise NotSupportedError(
'JSONObject() is not supported on this database backend.'
)
return super().as_sql(compiler, connection, **extra_context)
def as_postgresql(self, compiler, connection, **extra_context):
return self.as_sql(
compiler,
connection,
function='JSONB_BUILD_OBJECT',
**extra_context,
)
def as_oracle(self, compiler, connection, **extra_context):
class ArgJoiner:
def join(self, args):
args = [' VALUE '.join(arg) for arg in zip(args[::2], args[1::2])]
return ', '.join(args)
return self.as_sql(
compiler,
connection,
arg_joiner=ArgJoiner(),
template='%(function)s(%(expressions)s RETURNING CLOB)',
**extra_context,
)
class Least(Func):
"""
Return the minimum expression.