On Tue, Sep 29, 2009 at 4:27 PM, David Reynolds
<da...@reynoldsfamily.org.uk> wrote:
>
> Russ,
>
> On 29 Sep 2009, at 03:25, Russell Keith-Magee wrote:
>
>>  (1) know about the trick of instantiating an object with the
>> unrolled list version of a cursor, and
>
>
> Any chance you could expand upon this?

Sure. Assume a simple model:

class Author(Model):
    name = CharField()
    age = IntegerField()

Now, in your code, get a cursor and issue a SQL statement:

from django.db import connection.
cursor = connection.cursor()

cursor.execte('SELECT id, name, age FROM myapp_author')
result = cursor.fetchone()

At this point, result holds a tuple containing (id, name, age). You
can instantiate an instance of Author by unrolling this tuple:

instance = Author(*result)

if you want multiple instances, use cursor.fetchall():

results = cursor.fetchall()
instances = [Author(*result) for result in results]

You need to be a little careful with the fetchall version because you
could end up with a _lot_ of results - but that's really just the
standard cursor usage warning.

The real caveat: the order of the columns you SELECT *must* match the
order in which the fields are specified in the model. For example, if
you made the following SQL query:

cursor.execute('SELECT id, age, name FROM myapp_author')

the query will work fine, but you'll get a TypeError when you create
the object because 'age' can't be coerced into a string. If the two
fields that are out of order are the same data type, you won't get any
errors at all - you'll just get a badly represented instance. Hilarity
ensues.

This trick is exactly what Django does internally when it constructs
object instances. However, in the Django internals, it is a completely
automated process - Django issues the query and parses the results, so
there's no risk of getting the column order wrong.

There are some ways to work around the column ordering problem. For
example, you can interrogate the cursor to get the name of the columns
that have been returned. This is what Sean has done in his patch to
make the raw() call a little more robust. This code is completely
generic; hence the interest in adding this to core.

Yours,
Russ Magee %-)

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to