Python 3.x 发布嵌套模型SQLAlchemy棉花糖

Python 3.x 发布嵌套模型SQLAlchemy棉花糖,python-3.x,sqlalchemy,flask-sqlalchemy,flask-restplus,marshmallow-sqlalchemy,Python 3.x,Sqlalchemy,Flask Sqlalchemy,Flask Restplus,Marshmallow Sqlalchemy,我正试着将炼金术与棉花糖结合起来。我有一个FlaskAPI,其中包含一些资产和交易对。我想要这些模型之间的双向一对多关系。我有以下代码: class Asset(db.Model): __tablename__ = 'asset' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(255), unique=True, nullable=False) abbreviat

我正试着将炼金术与棉花糖结合起来。我有一个FlaskAPI,其中包含一些资产和交易对。我想要这些模型之间的双向一对多关系。我有以下代码:

class Asset(db.Model):
    __tablename__ = 'asset'

    id  = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), unique=True, nullable=False)
    abbreviation = db.Column(db.String(20), unique=True, nullable=True)
    trading_bases = relationship("TradingPair", back_populates="base_asset", foreign_keys="TradingPair.base_id")
    trading_quotes = relationship("TradingPair", back_populates="quote_asset", foreign_keys="TradingPair.quote_id")


class TradingPair(db.Model):
    __tablename__ = 'trading_pair'

    id  = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255), unique=True, nullable=False)

    # One to many (a pair can have only one base, but 1 asset can be the base of many pairs)
    base_id = db.Column(db.Integer, db.ForeignKey("asset.id"), nullable=False)
    base_asset = relationship("Asset", foreign_keys=[base_id], uselist=False, back_populates="trading_bases")

    # One to many (same reasoning)
    quote_id = db.Column(db.Integer, db.ForeignKey("asset.id"), nullable=False)
    quote_asset = relationship("Asset", foreign_keys=[quote_id], uselist=False, back_populates="trading_quotes")
使用以下资源进行交易对POST:

def post(self, name):
    pair = TradingPair.query.filter_by(name=name).first()
    if pair:
        return {"Error": "This resource already exists"}, 409

    data = request.get_json()
    schema = TradingPairSchema()
    try:
        pair = schema.load(data, session=db.session)
        if not pair.name == name:
            return {"Error": f"{name} does not correspond to name in data"}
        db.session.add(pair)
        db.session.commit()
        return {"Success":f"Added: {pair.name}"} 
    except ValidationError as e:
        return {"Error": e.messages}, 400
    except:
        return {"Error":"Database error"}, 500
我希望SQLAlchemy能够添加作为新交易对一部分发布的新资产。但是,如果我想使用以下JSON通过API发布新对:

{'name': 'DASHUSDT', 
 'base_asset': {
   'name': 'Dash', 
   'abbreviation': 'DASH'}, 
 'quote_asset': {
    'name': 'Tether', 
    'abbreviation': 
    'USDT'}}

这将正常工作,并按预期将该对添加到数据库中。当我尝试添加另一对包含Dash或Tether时,就会出现问题。该对将再次添加到DB中,并且违反了资产表上的“我的唯一性”约束。如何确保不创建新实例而使用现有资产?

我最后检查了资产是否存在,如果资产不存在,则将其添加到数据库中。我在交易对的POST功能中使用的代码是:

        loaded = schema.load(data, session=db.session)
        if not loaded.name == name:
            return {"Error": f"{name} does not correspond to name in data"}
        base = Asset.query.filter_by(abbreviation=loaded.base_asset.abbreviation).first()
        if not base:
            base = Asset(name=loaded.base_asset.name , abbreviation=loaded.base_asset.abbreviation)
            db.session.add(base)
        quote = Asset.query.filter_by(abbreviation=loaded.quote_asset.abbreviation).first()
        if not quote:
            quote = Asset(name=loaded.quote_asset.name, abbreviation=loaded.quote_asset.abbreviation)
            db.session.add(quote)
        pair = TradingPair(name=name, base_asset=base, quote_asset=quote)
        db.session.add(pair)
        db.session.commit()
当资产已经存在时,这似乎可以正常工作,但当通过交易对的POST插入新资产时,也不会崩溃。我在SQLAlchemy、Flask SQLAlchemy或Marshmallow SQLAlchemy中都找不到关于如何正确处理此问题的任何文档,但目前为止,这是有效的