我试图理解棉花糖模式的内省是如何工作的。下面是一个简单的代码示例:
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
没有字段,所以它只返回空的dict。我希望这个脚本返回[{"id": 0, "name": "Alice", "age": 25}, {"id": 1, "name": "Bob", "age": 26}]
,或者类似的东西。显然,数据库模型的自省没有发生。为什么不呢?如何修改此脚本以获得预期结果
为了完整起见,我正在使用Python 3.8.5,在我的环境中使用pip freeze
的结果如下:
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()
但这违背了完全自我反省的目的。我希望避免在两个地方定义字段
多亏了pjcunningham的评论,我才得以实现这一目标。正如他提到的,所要做的就是用
ma.SQLAlchemyAutoSchema
替换ma.SQLAlchemySchema
。此更改后,脚本返回所需的结果相关问题 更多 >
编程相关推荐