#11863: Add a method to the orm to create Model instances from raw sql queries
---------------------------------------------------+------------------------
          Reporter:  seanoc                        |         Owner:  seanoc
            Status:  assigned                      |     Milestone:  1.2   
         Component:  Database layer (models, ORM)  |       Version:  SVN   
        Resolution:                                |      Keywords:        
             Stage:  Unreviewed                    |     Has_patch:  1     
        Needs_docs:  1                             |   Needs_tests:  0     
Needs_better_patch:  0                             |  
---------------------------------------------------+------------------------
Comment (by seanoc):

 Thanks for the feedback Jacob!  I'm going to be swamped with work for the
 next week or two but getting these worked into the patch are the first
 thing on my queue once work lets up a bit.  In the mean time here's some
 quick responses:

     * Making kwargs and annotations available to the test suite is kinda
 gross. I don't think the tests really need to know that info: they just
 need to validate that the raw query works.
 I tend to agree, the main reason I did this was during initial development
 there were situations where real fields were being added as annotations
 instead of being passed into the {{{__init__}}} of the model.  Since this
 could have some significant side effects I wanted to make sure that I
 caught it happening going forward and this was the easiest way I thought
 of to test it.  I'll rework it so that those are no longer unneccesarrily
 exposed and develop a test with a model which will error if it doesn't
 receive all of it's fields in it's {{{__init__}}}.
     * The signature of raw() will, I think, promote bad SQL practice and
 could lead to SQL injection. Specifically, the standard DB-API interface
 is execute(query, params), but for raw()it'd be raw(query, params=params).
 That's a minor difference, but raw(query % params) is now shorter, so
 people'll use it. Please change the API of raw() to be raw(query, params,
 **kwargs).
 Good call.  Part of the goal here was to keep things relatively non-SQL
 specific so that the .raw() method could be implemented for non-relational
 back-ends.  That being said I think the query+params best practice is
 common enough across systems which would allow something resembling a raw
 query that this makes sense.
     * Please spell-check your comments.
     * Naming nit: no need for the Exception part of
 InsufficiantFieldsException; InsufficiantFields will suffice. Ditto for
 InvalidQueryException.
     * When you check for a SELECT query, make sure to strip() the query
 string (query.py line 57).
     * Please use fixtures in tests instead of that big setUp.
 Will do on all of these
     * Do you think RawQuerySet should cache results the same way QuerySet
 does? I think not, but we'll need to explain why that'd be.
 I've gone a bit back and forth on this one.  To be honest the main reason
 it doesn't right now is I've just been focusing on getting things working
 and getting the API hammered out.  At this point I'm inclined to try and
 be consistent with QuerySet's behavior and to cache results.  Then if
 somebody wants to hit the database again, they would need to be explicit
 and call raw() again to get a new RawQuerySet.  If anybody has a strong
 feeling/argument either way I'd be very happy to hear it.  This will
 probably be one of the last bits I implement in the patch.
     * Have you thought about integrating this with the lazy field support
 (QuerySet.defer()/QS.only())? Seems like a logical thing to support.
 Yes I have but so far I've really focused on just getting things to work
 and to get the API worked out.  I've basically been treating this as a
 "nice to have" aspect to the patch.  Once I get your other recommendations
 worked in and a first pass at the documentation complete I'll dig into
 what work would be required to implement this.
     * Is cursor.description supported across all Django's supported
 database backends (I think it's not). If not, the same API can still work
 -- probably by supplying a complete translations dict -- but we need to
 avoid erroring out if description isn't available.
 That's a very good question.  I'll try to do some testing/research to find
 out.  Either way I'll look at ways to handle cursor.description not being
 supported in a particular backend.
     * This has some implications w/r/t Alex Gaynor's multi-db work. You
 might want to try to get his thoughts on how you're handling connection
 and how that'll need to change.
 Alex, Russel, and I talked about this a bit during the Djangocon sprints.
 Their advice at the time was to go forward with developing against Django
 trunk.  Once Alex's multi-db work hits trunk we'll look at what will be
 needed to make sure that .raw() uses the right connection to get a cursor.
 In generally tho it should be a relatively small change.  To be safe I'll
 be sure that when I go to work in these recommendations, I'll do a review
 of how I'm handling the cursor and start to plan for the change.

-- 
Ticket URL: <http://code.djangoproject.com/ticket/11863#comment:12>
Django <http://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 this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to