数据库模型的Flask棉花糖模式内省是如何工作的?

2024-05-13 22:30:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图理解棉花糖模式的内省是如何工作的。下面是一个简单的代码示例:

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()

但这违背了完全自我反省的目的。我希望避免在两个地方定义字段


Tags: namefromimportappflaskdbagesqlalchemy
1条回答
网友
1楼 · 发布于 2024-05-13 22:30:07

多亏了pjcunningham的评论,我才得以实现这一目标。正如他提到的,所要做的就是用ma.SQLAlchemyAutoSchema替换ma.SQLAlchemySchema。此更改后,脚本返回所需的结果

相关问题 更多 >