Я пытаюсь обернуть голову вокруг SQLAlchemy в сочетании с Зефиром. У меня был 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 добавит новые активы, которые POSTed как часть новой торговой пары , Однако, если я хочу разместить новые пары через API, используя следующую команду: JSON:
{'name': 'DASHUSDT',
'base_asset': {
'name': 'Dash',
'abbreviation': 'DASH'},
'quote_asset': {
'name': 'Tether',
'abbreviation':
'USDT'}}
Это работает правильно, и пара добавляется в базу данных, как и ожидалось. Проблема возникает, когда я пытаюсь добавить другую пару, содержащую Da sh или Tether. Пара снова добавляется в базу данных, и мое ограничение уникальности для таблицы активов нарушается. Как я могу убедиться, что новый экземпляр не создан, а используется существующий ресурс?