Peewee: Composable queries

Created on 13 Jun 2018  路  4Comments  路  Source: coleifer/peewee

Hi,

I'm a elixir guy and use ecto as primary OR mapper. ecto has the nice feature to create composable queries. So you can save queries and then use them as input for other queries.

Example (from https://blog.drewolson.org/composable-queries-ecto/):

# query2 uses query as input

query  = from p in MyApp.Post,
         select: p

query2 = from p in query,
         where: p.published == true

MyApp.Repo.all(query2)

Another example (same source):

  def for_post(query, post) do
    from c in query,
     join: p in assoc(c, :post)
    where: p.id == ^post.id
  end

  def popular(query) do
    query |> where([c], c.votes > 10)
  end

  def published(query) do
    query |> where([c], c.published == true)
  end

# The composable queries make it very easy to reuse and improve the code semantics
# It's obvious that you first filter the published Posts, sort them and then return one record
last_post = Post
|> Post.published
|> Post.sorted
|> MyApp.Repo.one

end

Is something like this possible with peewee?

Most helpful comment

It's absolutely not executing any queries. They are lazily evaluated when you iterate the results. That would be ridiculous.

All 4 comments

Yes and no. Peewee, being written in Python, uses method-chaining to accomplish something like what ecto is doing.

With peewee you'd write:

query = Post.select()  # equiv to "select * from post"
query2 = query.where(Post.published == True)  # equiv to select * from post where published = true

Queries in peewee are composable in the sense, also, that they can be nested or combined to create new queries. For example:

# Get all published posts.
published = Post.select().where(Post.published == True)

# Get all comments that are on posts that were published.
comments_on_published = Comment.select().where(Comment.post.in_(published))

Does this answer your question?

Hi @coleifer,

Thanks for your ultra-fast response!

So under-the-hood peewee is executing multiple queries (in your 2nd example). Seems like an possible performance impact.

It's absolutely not executing any queries. They are lazily evaluated when you iterate the results. That would be ridiculous.

Ah, ok. Sorry for the wrong implication.

Thanks for your fast response again. I'll look into using it. 馃憤

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexpantyukhin picture alexpantyukhin  路  5Comments

hanxifu picture hanxifu  路  4Comments

ghost picture ghost  路  5Comments

mikemill picture mikemill  路  3Comments

mmongeon-aa picture mmongeon-aa  路  4Comments