发布嵌套模型 SQLAlchemy-Marshmallow
Posting Nested models SQLAlchemy-Marshmallow
我正在尝试将 SQLAlchemy 与 Marshmallow 结合使用。我有一个 Flask API,其中包含一些资产和交易对。我想要这些模型之间的双向一对多关系。我有以下代码:
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 添加作为新交易对的一部分 POST 的新资产。但是,如果我想通过 API 使用以下 JSON:
来 post 新对
{'name': 'DASHUSDT',
'base_asset': {
'name': 'Dash',
'abbreviation': 'DASH'},
'quote_asset': {
'name': 'Tether',
'abbreviation':
'USDT'}}
此操作正常,并且该对已按预期添加到数据库中。当我尝试添加另一对包含 Dash 或 Tether 时出现问题。该对再次添加到数据库中,并且违反了我对资产 table 的唯一性约束。如何确保不创建新实例但使用现有资产?
我最后检查了资产是否存在,如果不存在则将它们添加到数据库中。我在交易对的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 中找到任何关于如何正确处理此问题的文档,但就目前而言,这是有效的。
我正在尝试将 SQLAlchemy 与 Marshmallow 结合使用。我有一个 Flask API,其中包含一些资产和交易对。我想要这些模型之间的双向一对多关系。我有以下代码:
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 添加作为新交易对的一部分 POST 的新资产。但是,如果我想通过 API 使用以下 JSON:
来 post 新对{'name': 'DASHUSDT',
'base_asset': {
'name': 'Dash',
'abbreviation': 'DASH'},
'quote_asset': {
'name': 'Tether',
'abbreviation':
'USDT'}}
此操作正常,并且该对已按预期添加到数据库中。当我尝试添加另一对包含 Dash 或 Tether 时出现问题。该对再次添加到数据库中,并且违反了我对资产 table 的唯一性约束。如何确保不创建新实例但使用现有资产?
我最后检查了资产是否存在,如果不存在则将它们添加到数据库中。我在交易对的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 中找到任何关于如何正确处理此问题的文档,但就目前而言,这是有效的。