Selecting multiple records

We can use Model.select() to retrieve rows from the table. When you construct a SELECT query, the database will return any rows that correspond to your query. Peewee allows you to iterate over these rows, as well as use indexing and slicing operations:

  1. >>> query = User.select()
  2. >>> [user.username for user in query]
  3. ['Charlie', 'Huey', 'Peewee']
  4. >>> query[1]
  5. <__main__.User at 0x7f83e80f5550>
  6. >>> query[1].username
  7. 'Huey'
  8. >>> query[:2]
  9. [<__main__.User at 0x7f83e80f53a8>, <__main__.User at 0x7f83e80f5550>]

Select queries are smart, in that you can iterate, index and slice the query multiple times but the query is only executed once.

In the following example, we will simply call select() and iterate over the return value, which is an instance of Select. This will return all the rows in the User table:

  1. >>> for user in User.select():
  2. ... print user.username
  3. ...
  4. Charlie
  5. Huey
  6. Peewee

Note

Subsequent iterations of the same query will not hit the database as the results are cached. To disable this behavior (to reduce memory usage), call Select.iterator() when iterating.

When iterating over a model that contains a foreign key, be careful with the way you access values on related models. Accidentally resolving a foreign key or iterating over a back-reference can cause N+1 query behavior.

When you create a foreign key, such as Tweet.user, you can use the backref to create a back-reference (User.tweets). Back-references are exposed as Select instances:

  1. >>> tweet = Tweet.get()
  2. >>> tweet.user # Accessing a foreign key returns the related model.
  3. <tw.User at 0x7f3ceb017f50>
  4. >>> user = User.get()
  5. >>> user.tweets # Accessing a back-reference returns a query.
  6. <peewee.ModelSelect at 0x7f73db3bafd0>

You can iterate over the user.tweets back-reference just like any other Select:

  1. >>> for tweet in user.tweets:
  2. ... print(tweet.message)
  3. ...
  4. hello world
  5. this is fun
  6. look at this picture of my food

In addition to returning model instances, Select queries can return dictionaries, tuples and namedtuples. Depending on your use-case, you may find it easier to work with rows as dictionaries, for example:

  1. >>> query = User.select().dicts()
  2. >>> for row in query:
  3. ... print(row)
  4. {'id': 1, 'username': 'Charlie'}
  5. {'id': 2, 'username': 'Huey'}
  6. {'id': 3, 'username': 'Peewee'}

See namedtuples(), tuples(), dicts() for more information.