Flask SQLAlchemy多对多关联表新增出价字段的实现方法咨询
结论
完全可以实现,你当前使用的是无额外字段的简单多对多关联表(db.Table创建),仅支持存储两个关联表的外键,要加出价金额这类业务字段,需要将关联表改造为关联模型(即继承自db.Model的实体类)。
代码改造步骤
- 替换原有简单关联表为关联模型
import datetime # 可按需导入代理工具,兼容原有快速查询关联对象的写法 from sqlalchemy.ext.associationproxy import association_proxy # 替换原来的bid_table class Bid(db.Model): __tablename__ = "bid_table" # 两个外键联合作为主键,保证同一用户对同一艺术品的重复出价也可记录(如果要限制同一用户同一艺术品只能出价一次,这个联合主键刚好满足) user_id = db.Column(db.Integer, db.ForeignKey("user.user_id"), primary_key=True) item_id = db.Column(db.Integer, db.ForeignKey("artpiece.item_id"), primary_key=True) # 新增出价金额字段,也可按需加出价时间、出价状态等字段 bid_amount = db.Column(db.Numeric(10,2), nullable=False) bid_time = db.Column(db.DateTime, default=datetime.datetime.now) # 建立和User、Artpiece的关联关系 user = db.relationship("User", back_populates="bid_records") artpiece = db.relationship("Artpiece", back_populates="bid_records")
- 修改原有
User模型的关联配置
class User(db.Model): user_id = db.Column(db.Integer, unique=True, primary_key=True, nullable=False) # 注意你原代码里username类型写的是Integer,应该是笔误,建议改成String username = db.Column(db.String(40), unique=True, nullable=False) email = db.Column(db.String(50), unique =True, nullable=False) password = db.Column(db.String(60), nullable=False) creation_date = db.Column(db.DateTime, default=datetime.datetime.now) # 替换原来的bids关系 bid_records = db.relationship("Bid", back_populates="user", cascade="all, delete-orphan") # 加代理后仍可通过user.bids直接获取该用户出价过的所有艺术品,兼容原有写法 bids = association_proxy('bid_records', 'artpiece')
- 修改原有
Artpiece模型的关联配置
class Artpiece(db.Model): item_id = db.Column(db.Integer, unique=True, primary_key=True, nullable=False) artist = db.Column(db.String(40), nullable=False) buyer = db.Column(db.String(40), nullable=False) end_date = db.Column(db.String(40)) # 你原代码里highest_bid是String类型,建议改成Numeric类型存金额更稳妥 highest_bid = db.Column(db.Numeric(10,2)) # 替换原来的bids关系 bid_records = db.relationship("Bid", back_populates="artpiece", cascade="all, delete-orphan") # 加代理后仍可通过art.bidders直接获取所有出价的用户,按需添加即可 bidders = association_proxy('bid_records', 'user')
新增出价记录的写法
不需要再用原来多对多的append方法,直接创建Bid实例写入数据库即可:
# 写法1:直接传id new_bid = Bid(user_id=当前用户id, item_id=目标艺术品id, bid_amount=出价金额) db.session.add(new_bid) db.session.commit() # 写法2:传实体对象 user = User.query.get(用户id) artpiece = Artpiece.query.get(艺术品id) new_bid = Bid(user=user, artpiece=artpiece, bid_amount=1999.99) db.session.add(new_bid) db.session.commit()
常见查询示例
- 查询某用户的所有出价记录:
user.bid_records,可直接读取每条记录的bid_amount、bid_time、artpiece属性 - 查询某艺术品的出价从高到低排序:
sorted(artpiece.bid_records, key=lambda x:x.bid_amount, reverse=True)
内容的提问来源于stack exchange,提问作者Barry
相关产品推荐
相关产品推荐

