#18757: Examine ways to get rid of DB backend convert_values()
----------------------------------------------+--------------------
     Reporter:  akaariai                      |      Owner:  nobody
         Type:  Cleanup/optimization          |     Status:  new
    Component:  Database layer (models, ORM)  |    Version:  master
     Severity:  Normal                        |   Keywords:
 Triage Stage:  Unreviewed                    |  Has patch:  0
Easy pickings:  0                             |      UI/UX:  0
----------------------------------------------+--------------------
 The convert_values() method is responsible for converting database values
 to Python values. The conversion is used at least for aggregates, GIS and
 Oracle's query compiler.

 The problem with current implementation is two-fold:
   1. The model fields have no way of specifying new converters. This is
 problematic for 3rd party fields. They would need to do some kind of a
 dynamic patch to the backend's convert_values() method if they need
 convert_values() support.
   2. The different backends have slightly differing implementation for the
 same cases.

 In #13844 it was suggested that Field.to_python() method could be reused.
 It seems it does mostly the correct thing, but it is meant for validation,
 not converting DB values to Python. So, going that route would need at
 least some more investigation.

 One possible solution is something like this: A field has convert_values()
 method. The field can (and likely will) call a backend specific converter
 method. So, a custom field could do the following:
   1. Add converter methods to backends it supports:
 {{{
 def psycopg2_converter(self, value):
     return value.lower()
 try:
     from django.db.backends.postgresql_psycopg2.operations import
 DatabaseOperations
     DatabaseOperations.convert_myfield_value = psycopg2_converter
     # Not sure if this exact syntax works.
 except ImportError:
     pass
 # Or, if there is need for just a generic converter:

 from django.db.backends import BaseDatabaseOperations
 BaseDatabaseOperations.convert_myfield_value = my_generic_converter
 }}}
   2. The convert_values method of the field itself would be:
 {{{
 def convert_values(self, connection, value):
     return connection.convert_myfield_value(value)
 }}}

 A little complicated, but it is general. I think it would be fast enough.

 Most fields could just do the conversion directly in
 field.convert_values() without messing with the !DatabaseOperations at
 all. Core fields would not need to do any dynamic installation, as we
 could of course just install the converter into the source code.

 The above proposal is just one way to achieve what is needed. I do think
 there is some need for improvement here, but I am not at all sure the
 suggestion in this post is the way forward.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/18757>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to