7

I need to transfer all data from an SQL table to an html page. In SQLAlchemy I would do something like this:

class Author(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    first = db.Column(db.String(80))
    last = db.Column(db.String(80))


@app.route('/authors')
def get_authors():
    authors = Author.query.all()
    # Serialize the queryset
    result = authors_schema.dump(authors)
    return jsonify({'authors': result.data})

Is there a something like authors = Author.query.all() in peewee?

Radu
  • 8,561
  • 8
  • 55
  • 91
T1ber1us
  • 161
  • 1
  • 2
  • 6

4 Answers4

7

To my knowledge, a direct equivalent does not exist in peewee, though there is an all method in the Dataset extension, documented here. You can do this pretty easily using a list comprehension:

authors = [author for author in Author.select()]

Or even just authors = list(Author). However, if you're trying to return these as JSON, it won't work because your list of authors is populated by instances of Author and Flask's JSONEncoder will not work with this type out of the box. You can get around this by using peewee's dicts() method:

authors = [author for author in Author.select().dicts()]

The full example would look like this:

@app.route('/authors')
def get_authors():
    authors = [author for author in Author.select().dicts()]
    return jsonify(authors)

Instead of serializing using dicts I often use marshmallow. For example you create an author_schema like so:

from marshmallow import Schema, fields

class AuthorSchema(Schema):
    id = fields.Integer(dump_only=True)
    first = fields.String()
    last = fields.String()

author_schema = AuthorSchema()

and use it like so (not showing imports):

@app.route('/authors')
def get_authors():
    authors = author_schema(Author, many=True)
    return jsonify(authors)
Radu
  • 8,561
  • 8
  • 55
  • 91
  • Dear downvoter, would you please comment if there is anything wrong with the above? The code is tested and my answer is more complete than the others.. – Radu Aug 06 '20 at 02:22
  • advanced use case warning: when you do `authors = list(Author)` the final instances inside the list are lazy-loaded, but somehow it was using the full instance memory on my machine (OOM) during a big query. imagine you have images for an author and it is inadvertently fetching all of those somewhere – Kermit Sep 13 '22 at 18:19
4

so i make this.

@app.route('/authors')
def get_authors():
    authors = Author.select()
    return render_template('aurhors.html', authors=authors)

And in html something like this.

 {% for a in authors %}
 <p>{{a.author_name}}</p>
 {% endfor %}

I only in begining of studying python, so thank for help.

T1ber1us
  • 161
  • 1
  • 2
  • 6
1

What you're looking for is .dicts(), a method well-hidden in the docs, which returns an iterable peewee-specific type:

response = {'authors': []}
authors = Author.select()
for author in authors.dicts():
    response['authors'].append(author)
mijiturka
  • 434
  • 6
  • 18
0

Something like this should work of you're working with APIs:

return list(Account.select().dicts());
Pezhvak
  • 9,633
  • 7
  • 29
  • 39