【问题标题】:Flask-SQLAlchemy & Flask-Marshmallow Order with Orderline informationFlask-SQLAlchemy 和 Flask-Marshmallow Order 以及 Orderline 信息
【发布时间】:2022-07-03 18:22:44
【问题描述】:

对于餐厅应用程序,我尝试在 SQLAlchemy 中设置一个模式,其中包含每个订单的订单和订单行。我使用 Flask-SQLAlchemy 进行模型创建,使用 Flask-Marshmallow 进行序列化。

我想检索特定表的所有订单,并显示订单行及其产品信息。表格信息显示在订单的 JSON 结果上,但表格与订单具有 1 对 1 的关系,订单行与订单具有多对 1 的关系。如何在 orderlines 表中使用 order 的外键显示 orderlines 及其信息?

导入和设置

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow

app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + \
    os.path.join(basedir, 'restuarant.db')
db = SQLAlchemy(app)
ma = Marshmallow(app)

SQLAlchemy 模型订单、订单线、表格和产品

class Order(db.Model):
    __tablename__ = 'Orders'
    order_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    order_date = db.Column(db.DateTime, default=datetime.utcnow)
    total_price = db.Column(db.Float)
    table_id = db.Column(db.Integer, db.ForeignKey(
        'Tables.table_id'), nullable=False)
    order_items = db.relationship(
        'Order_item', backref=db.backref('order', lazy='joined'))

class Order_item(db.Model):
    __tablename__ = 'Order_items'
    order_item_id = db.Column(
        db.Integer, primary_key=True, autoincrement=True)
    quantity = db.Column(db.Integer)
    order_id = db.Column(db.Integer, db.ForeignKey(
        'Orders.order_id'))  # nullable = False
    product_id = db.Column(db.Integer, db.ForeignKey(
        'Products.product_id'))  # nullable = False

class Table(db.Model):
    __tablename__ = 'Tables'
    table_id = db.Column(db.Integer, primary_key=True)
    table_name = db.Column(db.String(20))
    orders = db.relationship(
        'Order', backref=db.backref('table', lazy='joined'))

class Product(db.Model):
    __tablename__ = 'Products'
    product_id = db.Column(db.Integer, primary_key=True)
    product_name = db.Column(db.String(50))
    description = db.Column(db.String(250))
    price = db.Column(db.Float)
    order_items = db.relationship(
        'Order_item', backref=db.backref('product', lazy='joined'))

棉花糖架构

class ProductSchema(ma.SQLAlchemySchema):
    class Meta:
        model = Product

    # Fields to expose
    product_id = ma.auto_field()
    product_name = ma.auto_field()
    description = ma.auto_field()
    price = ma.auto_field()


product_schema = ProductSchema()
products_schema = ProductSchema(many=True)


class TableSchema(ma.SQLAlchemySchema):
    class Meta:
        model = Table

    # Fields to expose
    table_id = ma.auto_field()
    table_name = ma.auto_field()


table_schema = TableSchema()
tables_schema = TableSchema(many=True)


class Order_ItemSchema(ma.SQLAlchemySchema):
    class Meta:
        model = Order_item

    # Fields to expose
    order_item_id = ma.auto_field()
    quantity = ma.auto_field()
    item_status = ma.auto_field()

    product = ma.Nested(ProductSchema)


order_item_schema = Order_ItemSchema()
order_items_schema = Order_ItemSchema(many=True)


class OrderSchema(ma.SQLAlchemySchema):
    class Meta:
        model = Order

    # Fields to expose
    order_id = ma.auto_field()
    order_date = ma.auto_field()
    total_price = ma.auto_field()

    #How to set up the items schema in Marshmallow?
    items = ma.List(ma.Nested(lambda: Order_ItemSchema()))
    table = ma.Nested(TableSchema)


order_schema = OrderSchema()
orders_schema = OrderSchema(many=True)

订单路线

@ app.route("/orders", methods=["GET", "POST"])
def orders():
    if request.method == "POST":
        pass
    else:
        orders = Order.query.filter_by(table_id=1).all()
        return jsonify(orders_schema.dump(orders))

JSON 输出

[
  {
    "order_date": "2022-04-10T13:34:33.891639", 
    "order_id": 1, 
    "table": {
      "table_id": 1, 
      "table_name": "Test table"
    }, 
    "total_price": 4.04
  }, 
  {
    "order_date": "2022-04-10T19:10:48.735628", 
    "order_id": 2, 
    "table": {
      "table_id": 1, 
      "table_name": "Test table"
    }, 
    "total_price": 2.02
  }
]

想要的结果

[
  {
    "order_date": "2022-04-10T13:34:33.891639", 
    "order_id": 1, 
    "table": {
      "table_id": 1, 
      "table_name": "Test table"
    },
    "orderlines": [
        {
            "order_item_id": 1,
            "quantity": 2,
            "order_id": 1,
            "product_id": 1
        },
        {
            "order_item_id": 2,
            "quantity": 4,
            "order_id": 1,
            "product_id": 2
        }
    ],
    "total_price": 4.04
  }
]

【问题讨论】:

    标签: python sqlalchemy flask-sqlalchemy flask-marshmallow


    【解决方案1】:

    看到the example of serializing a join后,我设法在Order_item 类上使用backref "order" 和marshmallow Nested 方法中的属性字段来检索订单商品。

    class OrderSchema(ma.SQLAlchemySchema):
        class Meta:
            model = Order
    
        # Fields to expose
        order_id = ma.auto_field()
        order_date = ma.auto_field()
        total_price = ma.auto_field()
    
        items = ma.Nested(order_items_schema, attribute='order')
        table = ma.Nested(TableSchema)
    
    
    order_schema = OrderSchema()
    orders_schema = OrderSchema(many=True)
    

    结果:

      {
        "items": [
          {
            "item_status": "Ordered", 
            "order_item_id": 1, 
            "product": {
              "description": "Nice test product 1", 
              "price": 1.01, 
              "product_id": 1, 
              "product_name": "Test product 1"
            }, 
            "quantity": 1
          }, 
          {
            "item_status": "Ordered", 
            "order_item_id": 2, 
            "product": {
              "description": "Nice test product 2", 
              "price": 2.02, 
              "product_id": 2, 
              "product_name": "Test product 2"
            }, 
            "quantity": 4
          }
        ], 
        "order_date": "2022-07-03T10:11:56.229125", 
        "order_id": 1, 
        "table": {
          "table_id": 1, 
          "table_name": "Test table"
        }, 
        "total_price": 9.09
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-08
      • 1970-01-01
      • 2021-08-04
      • 2021-04-19
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多