djangopostgresqldjango-modelsdjango-jsonfield

How to merge two JSONField fields


Postgres allows merging/concatenating two JSONB fields into one. Quoting the relevant Postgres docs:

jsonb || jsonb → jsonb - Concatenates two jsonb values.

As far as I can see, the Django ORM does not provide an operator for this type of concatenation. django.db.models.expressions.Combinable does not have a || operator.

django.contrib.postgres.search.SearchQueryCombinable has a || operator, but this class does not seem to apply here.

How can I merge two JSONFields using Django functions, but without evaluating the queryset?


Solution

  • Since expressions usually are of the mixin class Combinable, we can use the _combine method on an F field and customize the operator to be ||. ExpressionWrapper is necessary because Django cannot infer the output_field of our customized combination.

    from django.db import models
    from django.db.models import ExpressionWrapper, F
    
    class MyModel(models.Model):
        jsonfield1 = models.JSONField()
        jsonfield2 = models.JSONField()
    
    
    MyModel.objects.annotate(
        concatenated_jsonfields=ExpressionWrapper(
            F("jsonfield1")._combine(F("jsonfield2"), "||", reversed=False),
            output_field=models.JSONField(),
        )
    )