【问题标题】:How to use Marshmallow properly to insert new data on Mysql?如何正确使用 Marshmallow 在 Mysql 上插入新数据?
【发布时间】:2020-12-20 16:16:15
【问题描述】:

我将描述一个小型数据库结构:

一次拍卖有 N 个物品,一件物品可以在 N 次拍卖中。所以我们遇到了多对多的情况,找我的代码:

拍卖.py

from . import db, Base

itens = db.Table('auction_itens',
    db.Column('item_id', db.Integer, db.ForeignKey('item.id'), primary_key=True),
    db.Column('auction_id', db.Integer, db.ForeignKey('auction.id'), primary_key=True)
)

class Auction(Base):
    name = db.Column(db.String(255), nullable=False)
    itens = db.relationship('Item', secondary=itens, lazy='subquery',
        backref=db.backref('auctions', lazy=True))

项目.py

from . import db, Base

class Item(Base):
    name = db.Column(db.String(255), nullable=False)

这将创建以下结构:

这是我所期望的,但我的问题是在帖子中插入新数据库。所以让我们看看我的 Schema 和我的帖子来插入数据。

auctions_serializer.py

from .. import ma
from ..auctions import Auction
from .itens_serializer import ItemSchema
from marshmallow import fields

class AuctionSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Auction
        include_relationships = True
        load_instance = True
        include_fk = True

    itens = fields.Nested(ItemSchema, many=True)

itens_serializer.py

from .. import ma
from ..itens import Item


class ItemSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Item
        include_relationships = True
        load_instance = True

我的发帖路线:

@bp_auctions.route('/auctions', methods=['POST'])
def postAuctions():  
    auction_schema = AuctionSchema()
    auction = auction_schema.load(request.json)
    current_app.db.session.add(auction)
    current_app.db.session.commit()
    return_msg =  auction_schema.jsonify(auction)

    return return_msg, return_code

如果此代码收到包含以下 JSON 的帖子,则效果很好:

{
  "name": "test",
  "itens": ["item_one", "item_two"]
}

在这种情况下,代码将创建一个拍卖行,在 item 中创建两行,在 auction_item 中创建两行,这是完美的,但是如果我再次发送帖子,如果已经存在“item_one”和“item_two”,则序列化程序将不会搜索" 在项目表上,它将在项目表上创建另一行,所以在这种情况下,我的项目表将有 4 行,但有 2 个重复项。我的疑问是:

在基于 json 创建新项目之前,如何强制棉花糖在 DB 上进行搜索?有什么办法吗?

【问题讨论】:

    标签: python mysql many-to-many flask-sqlalchemy marshmallow


    【解决方案1】:

    我已经设法解决了这个问题,但它看起来不是最佳/最干净的解决方案:

    @bp_auctions.route('/auctions', methods=['POST'])
    def postAuctions():  
        auction_schema = AuctionSchema()
        itens_request = request.json.pop("itens")
        auction = auction_schema.load(request.json)
    
        itens_schema = ItemSchema()
        for item in itens_request:
            result = Item.query.filter_by(name=item["name"]).first()
            if result is not None:
                auction.itens.append(result)
            else:
                item = itens_schema.load(item)
                auction.itens.append(item)
                
        current_app.db.session.add(auction)
        current_app.db.session.commit()
        return_msg =  auction_schema.jsonify(auction)
    
        return return_msg, return_code
    

    这个解决方案的问题是:对于每一个 X 项的请求,都会在数据库上进行 X 次选择。

    如果有任何更大的问题,请 IDK。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-17
      • 1970-01-01
      • 2020-04-03
      相关资源
      最近更新 更多