-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Usage with Flask factory pattern? #74
Comments
That's how I'm doing it as well. Seems to be how people do it from my research. I haven't experienced any problems in the project. |
@lnunno Your code example looks correct. I would certainly merge a PR adding this to the docs. =) |
@sloria so I've spent a bunch of time digging on this after first landing on issue #44 From reviewing how this all works it appears that as of today, the init_app pattern mostly doesn't work the way people would expect. My expectation would be: # my_marshmallow_models.py
from flask_marshmallow import Marshmallow
ma = Marshmallow()
from my_dbmodels import SomeModel
class SomeModelSchema(ma.ModelSchema):
class Meta:
model = SomeModel Then in my factory: from my_db_module import db
from my_marshmallow_models import ma
app = Flask(__name__)
db.init_app()
ma.init_app(app) This doesn't work though. class ParentClass:
some_attr = 1
class ChildClass(ParentClass):
pass
a = ChildClass()
print(a.some_attr)
ParentClass.some_attr = 2
b = ChildClass()
print(a.some_attr)
print(b.some_attr)
# output:
# 1
# 2
# 2 I'm a bit out of my depth here though on the meta classes, I see the release note for marshmallow 2.0.0b1 mentions OPTIONS_CLASS being validated earlier but I don't really understand the lifecycle of all these variables once metaclasses are involved. Should this monkey patch actually be handled changing DummySession into a proxy class of some kind so that it's resolved later? Requiring app construction before model definition becomes extremely restrictive in terms of import orders and file structure for large apps and mostly makes the init_app non-functional |
So the way I have it working is to first create the marshmallow instance in a separate module: # schema.py
import flask_marshmallow
ma = flask_marshmallow.Marshmallow() Your database module: # database.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy() Your model class: # models.py
from app.schema import ma
from app.database import db
class MyModel(db.Model):
""" Model definition """
class MySchema(ma.ModelSchema):
class Meta:
model = MyModel Then in your factory: # __init__.py
from flask import Flask
def create_app():
flask_app = Flask(__name__)
# Initialize database connector
from app.database import db
db.init_app(flask_app)
# Register Marshmallow parsing
from app.schema import ma
ma.init_app(flask_app)
# Now import any module that uses your model declarations
from app.models import MyModel |
Don't think this is really an issue to be honest. One initializes flask marshmallow the same way you would any other flask plugin, when it comes to the app factory structure. I Highly recommend taking a look at this if you want a more in-depth description of what I mean: https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xv-a-better-application-structure
You can use marshmallow and sqlalchemy we defined above like so:
|
I just attempted this and I get an error along the lines of |
ma.init_app(app) replace DummySession() by db.session but its too late, schemas have already been created, so replace it as soon as ma have been initialized. marshmallow-code/flask-marshmallow#44 marshmallow-code/flask-marshmallow#74 marshmallow-code/flask-marshmallow#111
ma.init_app(app) replace DummySession() by db.session but its too late, schemas have already been created, so replace it as soon as ma have been initialized. marshmallow-code/flask-marshmallow#44 marshmallow-code/flask-marshmallow#74 marshmallow-code/flask-marshmallow#111
ma.init_app(app) replace DummySession() by db.session but its too late, schemas have already been created, so replace it as soon as ma have been initialized. marshmallow-code/flask-marshmallow#44 marshmallow-code/flask-marshmallow#74 marshmallow-code/flask-marshmallow#111
For anyone facing the same error as @amaschas , I think the correct way getting around this is by importing your blueprints inside of the |
I wasn't able to find this in the docs, but what is the recommended way to use this library with the Flask factory pattern?
My approach was to initialize the Marshmallow object in my models file and then in
register_extensions
callMarshmallow.init_app
like so:Is this the recommended approach? It seems to work while trying it out from the flask shell.
The text was updated successfully, but these errors were encountered: