1

現在、Flask、SQLAlchemy、および Marshmallow を使用して API を構築しています。次のようなかなり単純なDBモデルがあります。

class Transaction(db.Model):
    #Transaction Model
    __tablename__ = 'transactions'
    id = db.Column(db.Integer, primary_key = True)
    created_at = db.Column(db.DateTime, default=datetime.datetime.now)
    date = db.Column(db.DateTime)
    description = db.Column(db.Text)
    amount = db.Column(db.Float)
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
    category = db.relationship('Category', uselist=False, lazy='select')
    sub_category_id = db.Column(db.Integer, db.ForeignKey('sub_categories.id'))
    sub_category = db.relationship('SubCategory', uselist=False, lazy='select')
    account = db.Column(db.Integer, db.ForeignKey('accounts.id'))
    inner_transfer = db.Column(db.Boolean)



class Category(db.Model):
    __tablename__ = 'categories'
    id = db.Column(db.Integer, primary_key = True)
    category = db.Column(db.String(64), unique = True)
    transaction = db.relationship('Transaction')

私のマシュマロスキーマは次のようになります。

class CategorySchema(ma.ModelSchema):
    class Meta:
        model = Category


category_schema = CategorySchema()
categories_schema = CategorySchema(many=True)

class TransactionSchema(ma.ModelSchema):
    class Meta:
        model = Transaction
        include_fk = True

そして、非常に単純な API エンドポイント:

@api.route('/transactions', methods=['GET'])
def transactions():
    all_transactions = Transaction.query.all()
    for transaction in all_transactions:
        transaction.category = Category.query.filter_by(id=transaction.category_id).first()
        print(transaction.category)
    items, errors = transactions_schema.dump(all_transactions)
    return jsonify(items)

私の問題: 主キーの代わりにカテゴリ名を持つ JSON 応答を作成するにはどうすればよいですか? 「for transaction in all tr​​ansactions」ビットを試してみましたが、印刷ステートメントでカテゴリ名を取得しましたが、JSON 応答には表示されません...

データベース モデルの書き方がよくわかりません。私が特にこだわっているのは、db.relationship です。私の Transaction クラスで宣言しても、Category クラスの主キーのみが表示されるだけなので、役に立たないようです。Flask-SQLAlchemy のドキュメントを上下に読みましたが、よくわかりません。

どんな助けや指針も大歓迎です!

ありがとう!

4

1 に答える 1

7

これを実際に示すためにモデルの単純なバージョンを作成し、データベースに 2 つのテスト レコードをシードしました。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
ma = Marshmallow(app)

# DB Models
class Transaction(db.Model):
    #Transaction Model
    __tablename__ = 'transactions'
    id = db.Column(db.Integer, primary_key = True)
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
    category = db.relationship('Category', uselist=False, lazy='select')

class Category(db.Model):
    __tablename__ = 'categories'
    id = db.Column(db.Integer, primary_key = True)
    category = db.Column(db.String(64), unique = True)
    transaction = db.relationship('Transaction')

# Schema
class TransactionSchema(ma.ModelSchema):
    class Meta:
        model = Transaction
        include_fk = True
    # Here is the function, you do not not need to define all fields you want to dump
    category_name = ma.Function(lambda obj: obj.category.category)

次に呼び出します: TransactionSchema(many=True).dump(Transaction.query.all()).data

収量: [{u'category': 1, u'category_id': 1, u'category_name': u'Test1', u'id': 1}, {u'category': 2, u'category_id': 2, u'category_name': u'Test2', u'id': 2}]

関数でフィールドを上書きして、ダンプのみにすることもできます。

class TransactionSchema(ma.ModelSchema):
class Meta:
    model = Transaction
    include_fk = True
category = ma.Function(lambda obj: obj.category.category, dump_only=True)

収量: [{u'category': u'Test1', u'category_id': 1, u'id': 1}, {u'category': u'Test2', u'category_id': 2, u'id': 2}]

于 2016-09-20T15:48:16.617 に答える