Peewee: Results as dict/array of dict?

Created on 5 Dec 2012  Â·  9Comments  Â·  Source: coleifer/peewee

It would be grand if one could do something like this:

    >>> m = Model()
    >>> print m.select()
    [{'id':1, 'name':'foo'},{'id':2, 'name':'bar'}]

i.e., returning each row as a dict. This would be especially handy for returning JSON result sets, and could probably be done using iter to return self._data for the model.

All 9 comments

Edit

This issue was 8 years old when it was brought to my attention again. The information is no longer correct. For quite a long time Peewee has supported the following chainable query methods to change the row-type: dicts(), tuples() and namedtuples()

See comment:

https://github.com/coleifer/peewee/issues/134#issuecomment-704935841


I'm not sure why this should be a part of peewee itself, unless for performance reasons you're concerned about the overhead of class creation. You can see in flask-peewee some helpers already exist:

You can save by not creating model instances by iterating over the cursor:

db = SqliteDatabase(...)

query = SomeModel.select()
cursor = db.execute(query)

ncols = len(cursor.description)
colnames = [cursor.description[i][0] for i in range(ncols)]
results = []

for row in cursor.fetchall():
    res = {}
    for i in range(ncols):
        res[colnames[i]] = row[i]
    results.append(res)

If you want to get even more low-level, you can take the sql generated by peewee and use a row factory:

Well, actually, because it's cumbersome to do that even for single rows - getting a dict out of a row makes it much easier to do functional coding than iterating through the column names, and even though I usually do use row factories when using SQL directly, that's the kind of thing I expect a model to do for me.

So please consider doing this, at least for single rows.

(also, I'm not using flask)

On Dec 5, 2012, at 03:00 , Charles Leifer [email protected] wrote:

I'm not sure why this should be a part of peewee itself, unless for performance reasons you're concerned about the overhead of class creation. You can see in flask-peewee some helpers already exist:

https://github.com/coleifer/flask-peewee/blob/master/flask_peewee/serializer.py
https://github.com/coleifer/flask-peewee/blob/master/flask_peewee/utils.py#L65
You can save by not creating model instances by iterating over the cursor:

db = SqliteDatabase(...)

query = SomeModel.select()
cursor = db.execute(query)

ncols = len(cursor.description)
colnames = [cursor.description[i][0] for i in range(ncols)]
results = []

for row in cursor.fetchall():
res = {}
for i in range(ncols):
res[colnames[i]] = row[i]
results.append(res)
If you want to get even more low-level, you can take the sql generated by peewee and use a row factory:

http://docs.python.org/2/library/sqlite3.html#row-objects
—
Reply to this email directly or view it on GitHub.

If it's not for performance reasons, you could probably just use a helper @coleifer linked to and so something like that. I haven't tested this though.

from itertools import imap
from flask_peewee.utils import get_dictionary_from_model

for dct in imap(get_dictionary_from_model, model.select()):
     print dct

Or if that's too much code to write everytime, define your own BaseModel and wrap select.

Yeah, as @squiddy said -- there are a lot of ways to do this, and if it is not for performance reasons just wrap select(), or give your model instances an "to_dict()" method or something.

:japanese_ogre:

As I do In MySQL (as I didn't check others):

  1. select().execute() in one step
  2. iterate through cursorwrapper
  3. getting values by literal column names through Model attributes instead of numeric indexing, as former is more straightforward for me
cursorwrapper = SomeModel.select().execute()

colnames = [name[0] for name in cursorwrapper.cursor.description]
results = []

for row in cursorwrapper:
    res = {}
    for cname in colnames:
        res[cname] = getattr(row, cname)
    results.append(res)

This is 8 years old. For quite a long time, Peewee has supported this out-of-the-box with the following query methods:

@coleifer Thank you for your info and your work.

Though as @coleifer pointed out that this is a 8 years old post, but as this github issue is among the top finds of search engines regarding this topic and I didn't find a good example code for usage of the pretty useful dicts() method (thank to @coleifer of course), I decided to post one for future readers:

query = SomeModel.select().dicts()

for row in query:
    print(type(row))

Out:

<class 'dict'>
<class 'dict'>
.
.
<class 'dict'>
Was this page helpful?
0 / 5 - 0 ratings

Related issues

aellwein picture aellwein  Â·  3Comments

vkrizan picture vkrizan  Â·  3Comments

alexlatchford picture alexlatchford  Â·  4Comments

GMaxera picture GMaxera  Â·  4Comments

lucasrc picture lucasrc  Â·  5Comments