【问题标题】:Nested fields with mashmallow_sqlalchemy and flask_marshmallow带有 mashmallow_sqlalchemy 和 flask_marshmallow 的嵌套字段
【发布时间】:2023-03-14 09:57:01
【问题描述】:

我正在尝试获取嵌套的序列化输出,但我得到的只是多对一表主键的“多”端。

预期输出:

[{'part_numbers': 
                 {'part_number': '23103048', 'description': 'blue product'},
  'machines': 2,
  'percent_complete': 5.0,
  'serial_number': '001',
  'timestamp_created': 2020-03-12T15:4:23.135098},
 {'part_numbers': 
                 {'part_number': '44444009', 'description': 'red product'},
  'machines': 1,
  'percent_complete': 60.0,
  'serial_number': '002',
  'timestamp_created': '2020-03-12T15:44:23.135098'}]

实际输出:

[{'id': 3,
  'machines': 2,
  'percent_complete': 5.0,
  'serial_number': '001',
  'timestamp_created': 2020-03-12T15:4:23.135098},
 {'id': 1,
  'machines': 1,
  'percent_complete': 60.0,
  'serial_number': '0002',
  'timestamp_created': '2020-03-12T15:44:23.135098'}]

这些是我的文件。我尝试将part_numbers = ma.Nested(PartNumbers) 添加到Machine 内部models.py 架构中,但它并没有改变结果!

my_app
|--- my_app
     |--- \__init\__.py
     |--- models.py
     |--- views.py

models.py

from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from marshmallow_sqlalchemy import SQLAlchemyAutoSchema

db = SQLAlchemy()
ma = Marshmallow()

### Models ###

class Machine(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    serial_number = db.Column(db.Text, unique=True)
    percent_complete = db.Column(db.Float)
    part_number_id = db.Column(db.Integer, db.ForeignKey('PartNumbers.id'))
    timestamp_created = db.Column(db.DateTime, default=datetime.utcnow)

class PartNumbers(db.Model):
    __tablename__ = 'PartNumbers'

    id = db.Column(db.Integer, primary_key=True)
    part_number = db.Column(db.Text, unique=True)
    description = db.Column(db.Text)
    machines = db.relationship('Machines', backref='machines', lazy='dynamic')


### Schemas ###

class PartNumbersSchema(SQLAlchemyAutoSchema):
    class Meta:
        model = PartNumbers
        include_fk = True

class MachineSchema(SQLAlchemyAutoSchema):
    class Meta:
        model = Machines
        include_relationships = True

__init__.py

from flask import Flask
from .models import db, ma
from .views import my_app

app = Flask(__name__)
db.init_app(app)
ma.init_app(app)
app.register_blueprint(my_app)

views.py

from flask import Blueprint
from .models import db, Machines, MachineSchema, PartNumbers

my_app = Blueprint("my_app", __name__)

machines_schema = MachineSchema(many=True)

@my_app.route('/')
def home()
    machines = db.session.query(Machines).all()
    return machines_schema.dump(machines)

【问题讨论】:

    标签: flask-sqlalchemy flask-marshmallow marshmallow-sqlalchemy


    【解决方案1】:
    1. 在 Machine 类中定义 part_number:

      class Machine(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        serial_number = db.Column(db.Text, unique=True)
        percent_complete = db.Column(db.Float)
        part_number_id = db.Column(db.Integer, db.ForeignKey('PartNumbers.id'))
        timestamp_created = db.Column(db.DateTime, default=datetime.utcnow)
        part_numbers = db.relationship('PartNumbers')
      
    2. 您必须在 MachineSchema 中明确定义 part_numbers:

      from marshmallow_sqlalchemy import fields
      class MachineSchema(SQLAlchemyAutoSchema):
        class Meta:
          model = Machines
        part_numbers = fields.Nested(PartNumbersSchema)
      

    我假设 part_numbers 是单个对象(1:1 关系)。否则,您必须将 many=True 添加到 part_numbers。

    更多详情:https://marshmallow.readthedocs.io/en/stable/nesting.html

    [编辑以在评论中加入更正]

    【讨论】:

    • 是的!这似乎奏效了,除了我必须使用part_number = db.relationship('PartNumbers')。当我用 foreign_keys=[id] 参数尝试它时,它倒下了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-02
    • 1970-01-01
    相关资源
    最近更新 更多