我试图了解 Marshmallow Schemas 的内省是如何工作的。这是一个简单的代码示例:
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from pprint import pprint
db_file = "database.db"
if os.path.isfile(db_file):
os.remove(db_file)
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{db_file}"
app.app_context().push()
db = SQLAlchemy(app)
ma = Marshmallow(app)
class Person(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
age = db.Column(db.Integer)
class MySchema(ma.Schema):
class Meta:
model = Person
sqla_session = db.session
db.create_all()
alice = Person(name="Alice", age=25)
bob = Person(name="Bob", age=26)
db.session.add(alice)
db.session.add(bob)
db.session.commit()
persons = Person.query.all()
schema = MySchema(many=True)
result = schema.dump(persons)
pprint(result)
当我运行这个脚本时,我得到的结果是[{}, {}]
. 这告诉我它确实Person
从数据库中检索了对象,但是Schema
没有字段,所以它只返回空字典。我希望这个脚本返回[{"id": 0, "name": "Alice", "age": 25}, {"id": 1, "name": "Bob", "age": 26}]
,或类似的东西。显然,数据库模型的自省并没有发生。为什么不?我应该如何修改这个脚本以获得预期的结果?
为了完整起见,我使用的是 Python 3.8.5,pip freeze
在我的环境中 a 的结果是这样的:
alembic==1.4.3
aniso8601==8.0.0
attrs==20.2.0
click==7.1.2
Flask==1.1.2
flask-marshmallow==0.14.0
Flask-Migrate==2.5.3
flask-restx==0.2.0
Flask-Script==2.0.6
Flask-SQLAlchemy==2.4.4
itsdangerous==1.1.0
Jinja2==2.11.2
jsonschema==3.2.0
Mako==1.1.3
MarkupSafe==1.1.1
marshmallow==3.8.0
marshmallow-sqlalchemy==0.23.1
psycopg2-binary==2.8.6
pyrsistent==0.17.3
python-dateutil==2.8.1
python-editor==1.0.4
pytz==2020.1
six==1.15.0
SQLAlchemy==1.3.20
Werkzeug==0.16.1
注意:我知道我可以通过MySchema
像这样修改我的类来让它工作:
class MySchema(ma.SQLAlchemySchema):
class Meta:
model = Person
sqla_session = db.session
id = ma.auto_field()
name = ma.auto_field()
age = ma.auto_field()
但这违背了完全自动内省的目的。我想避免在两个地方定义字段。