【发布时间】:2018-07-10 14:26:40
【问题描述】:
Flask-Marshmallow documentation 对Marshmallow.init_app() 有这样的看法
使用扩展程序初始化应用程序。
code behind it 似乎做了一些与 SQLAlchemy 会话管理相关的重要事情:
def init_app(self, app):
app.extensions = getattr(app, 'extensions', {})
# If using Flask-SQLAlchemy, attach db.session to ModelSchema
if has_sqla and 'sqlalchemy' in app.extensions:
db = app.extensions['sqlalchemy'].db
self.ModelSchema.OPTIONS_CLASS.session = db.session
app.extensions[EXTENSION_NAME] = self
但我一直在使用和开发我的应用程序一段时间,但没有在任何地方调用init_app,而且它看起来运行良好。我正在使用 SQLAlchemy、Flask-SQLAlchemy 和 Marshmallow-SQLAlchemy(以及 Flask-Marshmallow)。
不执行ma.init_app(app) 会导致什么问题,为什么一切似乎都正常?
目前,我有一个database 和一个schema 模块; database 看起来像这样:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Customer(db.Model):
...
和schema 这样:
from flask_marshmallow import Marshmallow
from database import Customer
ma = Marshmallow()
class CustomerSchema(ma.ModelSchema):
class Meta:
model = Customer
在我的顶级__init__.py 中,我正在这样做:
from flask import Flask
from database import db
app = Flask(__name__)
db.init_app(app)
with app.app_context():
db.create_all()
这是一个 MVCE(放入 mvce/__init__.py,使用 PYTHONPATH=. FLASK_APP=mvce flask run 运行,然后向 localhost:5000 发出 POST 请求,并将 name 表单字段设置为某个值,然后发出 GET 请求以查看 @ 987654338@ 已正确提交到数据库):
from flask import Flask, request
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
@app.route("/")
def get():
return CustomerSchema(many=True).jsonify(Customer.query.all())
@app.route("/", methods=["POST"])
def new():
customer, errors = CustomerSchema().load(request.form)
if errors:
return errors, 400
db.session.add(customer)
db.session.commit()
return CustomerSchema().jsonify(customer)
db = SQLAlchemy()
class Customer(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
ma = Marshmallow() # Not passing `app`
class CustomerSchema(ma.ModelSchema):
class Meta:
model = Customer
db.init_app(app)
with app.app_context():
db.create_all()
# Note that we don't ever call `ma.init_app(app)`!
【问题讨论】:
-
您目前如何在 Flask 应用程序中初始化 Marshmallow?像这样
ma = Marshmallow(app)? -
@OluwafemiSule 目前我在做
ma = Marshmallow()(它在一个单独的模块中,所以我无权访问app)。 -
如果您认为需要通过子类化
ma.ModelSchema从模型构建您的 api 模式,那么您需要使用ma.init_app初始化您的应用程序,并将Flask实例传递给它。我假设你目前只是在使用ma.Schema。 -
@OluwafemiSule 不,我正在使用 ModelSchema。我已经用一些代码更新了这个问题。
-
@Josh 回答你的两个问题,是的。
标签: python flask sqlalchemy flask-sqlalchemy marshmallow