質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

4259閲覧

Python: flask_marshmallowを使ってjsonを返すプログラム

kei11

総合スコア1

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/12/10 14:35

Python: flask_marshmallowを使ってjsonを返すプログラム

表題の通り、flask、marshmallow、sqlalchemyを使って、getアクセスに対して、データベースから値を取得し、jsonを返すプログラムを作っています。

現在、データベースに接続し、値をUserオブジェクトとして取得できている状態で、marshmallowを使ってjsonに変換するところでエラーが出ております。

発生している問題・エラーメッセージ

TypeError: 'User' object is not iterable

Userオブジェクトは反復不可能であるといった旨のメッセージのようです。

router.py

python

1@bp.route('users/edit/<int:id>', methods=['GET']) 2def edit_user(id): 3 usr = users.find_user(id) 4 usr_schema = users.UserSchema(many=True) 5 return jsonify({"users": usr_schema.dump(usr).data})

return jsonify({"users": usr_schema.dump(usr).data})のラインでエラーが起こっております。

users.py

class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True, nullable=False) name = db.Column(db.String(255, convert_unicode=True), nullable=False) pwd = db.Column(db.String(255, convert_unicode=True), nullable=False) mail = db.Column(db.String(255, convert_unicode=True), nullable=False) age = db.Column(db.Integer, nullable=False) created_at = db.Column(db.DateTime, nullable=False, default=datetime.now) updated_at = db.Column(db.DateTime, nullable=False, default=datetime.now, onupdate=datetime.now) class UserSchema(ma.SQLAlchemyAutoSchema): class Meta: model = User def find_user(id): usr = db.session.query(User).filter(User.id == id).first() return usr

使用ツール・フレームワーク

python 3.9
flask 1.1.2
SQLAlchemy 1.3.20
Marshmallow 3.9.1

参考リンク

https://qiita.com/voygerrr/items/4c78d156fc91111798d5

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

flask、marshmallow、sqlalchemyを使って

とありますが、sqlalchemyのmodelに「db.*」という記述があるため「Flask-SQLAlchemy」を使っていると判断しました。
(db = SQLAlchemy(app)の記述があるコードが提示されていないので推測です)
同じ理屈でmarshmallowも「flask-marshmallow」だと考えて回答します。

Flask-Marshmallowのドキュメントによると、Flask-SQLAlchemyのモデルを使うにはまず以下のインストールが必要のようです。

pip install -U flask-sqlalchemy marshmallow-sqlalchemy

(もちろんflask-marshmallowも必要です。)

ソース上での初期化は以下の順番で行う必要があるようです。

python

1db = SQLAlchemy(app) 2ma = Marshmallow(app)

flask-marshmallowのモデルでは、ma.SQLAlchemySchemama.SQLAlchemyAutoSchemaを指定したモデル作成が必要のようです。

python

1class AuthorSchema(ma.SQLAlchemySchema): 2 3# or 4 5class BookSchema(ma.SQLAlchemyAutoSchema):

Autoがついていない方はカラム1つ1つを定義している感じで、Autoの方はinclude_fk = Trueにすれば勝手にやってくれる感じでしょうか?

Marshmallowは使ったことがないので、適当なテーブルを作成して動かしてみました。
質問文にあるモデルだとカラムが多くて面倒だったので、適当なモデルを作っています。

以下が動かしてみたソースです。
tableはdb.create_all()で先に作成しました。
実行方法は以下です。[2]を実行すると、all()で取得した結果が表示されます。

  1. ブラウザでlocalhost:5000/add_dataにアクセス。
  2. ブラウザでlocalhost:5000/show_dataにアクセス。

python

1# app.py 2from flask import Flask, jsonify 3from flask_sqlalchemy import SQLAlchemy 4from flask_marshmallow import Marshmallow 5 6 7from uuid import uuid4 8 9app = Flask(__name__) 10 11db = SQLAlchemy(app) 12ma = Marshmallow(app) 13 14app.config[ 15 'SQLALCHEMY_DATABASE_URI'] = \ 16 'mysql+mysqlconnector://{user}:{password}@{host}:{portnumber}/{database}?charset=utf8&' \ 17 'auth_plugin=mysql_native_password'.format( 18 user='user', 19 password='password', 20 host='localhost', 21 portnumber=3306, 22 database='test_db' 23 ) 24 25 26class User(db.Model): 27 __tablename__ = 'user' 28 id = db.Column('id', db.String(36), nullable=False, primary_key=True) 29 name = db.Column('name', db.String(10), nullable=False) 30 password = db.Column('password', db.String(24), nullable=False) 31 32 33class UserSchema(ma.SQLAlchemySchema): 34 class Meta: 35 model = User 36 id = ma.auto_field() 37 name = ma.auto_field() 38 password = ma.auto_field() 39 40 41@app.route('/add_data') 42def add_data(): 43 user = User(id=str(uuid4()), name='test name', password='Test_password123!#%') 44 db.session.add(user) 45 db.session.commit() 46 return 'added' 47 48 49@app.route('/show_data') 50def show_data(): 51 user = db.session.query(User).filter().all() 52 user_schema = UserSchema(many=True) 53 return jsonify(user_schema.dump(user)) 54 55 56if __name__ == '__main__': 57 app.run()

pip freezeの結果を以下に記載します。

text

1# pip freeze 2click==7.1.2 3Flask==1.1.2 4flask-marshmallow==0.14.0 5Flask-SQLAlchemy==2.4.4 6itsdangerous==1.1.0 7Jinja2==2.11.2 8MarkupSafe==1.1.1 9marshmallow==3.9.1 10marshmallow-sqlalchemy==0.24.1 11mysql-connector==2.2.9 12six==1.15.0 13SQLAlchemy==1.3.20 14Werkzeug==1.0.1 15

投稿2020/12/11 01:28

FiroProchainezo

総合スコア2392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kei11

2020/12/11 02:34

ご回答ありがとうございます。 推測されたパッケージを使用しており、環境はほぼ同じかと思います。 記述不足で申し訳ありません。 回答を参考にさせていただいたところ、原因は、db~.first()で取得した1件のデータに対し複数件を処理するコードを記述していたことにありました。 具体的には、UserSchema(many=True)のmany=Trueをなくすことで解決をする事ができました。 詳細なご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問