[Answered ]-Writing to SQL yields different results with shell / django

1👍

By overriding get_prep_value, you are serializing twice. Indeed, once in your myJSONField, and a second time by the get_db_prep_value function which uses get_prep_value as a helper function.

Indeed, if we inspect the source code [GitHub], we see:

def get_db_prep_value(self, value, connection, prepared=False):
    if not prepared:
        value = self.get_prep_value(value)
    # …
    return connection.ops.adapt_json_value(value, self.encoder)

depending on the connection itself, Django can then send for example a BSON blob, or a JSON. Except for PostgreSQL, it encodes the data with [GitHub]:

def adapt_json_value(self, value, encoder):
    return json.dumps(value, cls=encoder)

if you override get_prep_value, it converts it to a string, and then you JSON serialize it a second time.

One can implement a custom backend that would pass ensure_ascii=False, a poor man’s solution would be to just inject this through monkey patching. For example in the AppConfig:

# app_name/apps.py

from django.apps import AppConfig


class AppConfig(AppConfig):
    name = "app_name"

    def ready(self):
        def adapt_json_value(self, value, encoder):
            return json.dumps(value, ensure_ascii=False, cls=encoder)

        from django.db.backends.base.operations import BaseDatabaseOperations

        BaseDatabaseOperations.adapt_json_value = adapt_json_value

of course we then omit the get_prep_value in the myJSONField, which also basically nullifies myJSONField over JSONField.

Leave a comment