python-3.x - 在 SQLAlchemy 中引用同一表列的多个外键
问题描述
我正在创建一个评级系统。评级是一个表格,其中包含作为行的各个评级。每个评级都有一个“评级者”和一个“评级者”。这两列通过外键引用不同的表“用户”。但是,它们都引用了相同的 user.id 列。代码:
class Rating(db.Model):
id = db.Column(db.Integer, primary_key=True)
rater_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
ratee_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
以下是它们在 User 类(表)中的表示方式:
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(32), unique=True, nullable=False)
ratesOfOthers = db.relationship('Rating', backref='rater', lazy=True)
ratingsByOthers = db.relationship('Rating', backref='ratee', lazy=True)
现在,当我尝试使用这种关系时,会出现以下错误:
sqlalchemy.exc.AmbiguousForeignKeysError:无法确定关系 User.ratesOfOthers 上的父/子表之间的连接条件 - 有多个外键路径链接表。指定“foreign_keys”参数,提供那些列的列表,这些列应该被视为包含对父表的外键引用。
我尝试在 User 类中使用 foreign_keys 参数,但没有任何效果。任何帮助,将不胜感激。
解决方案
假设是在您的场景中,用户可以对其他用户进行评分,并且他们(他们自己)可以被评分。基本上,有一个表称为User
引用应用程序中的其他用户。
一个类的实例链接到同一类的其他实例的关系称为自引用关系,这正是您在这里所拥有的。
这是一个图表,它代表了这种跟踪评级的自引用多对多关系:
该Ratings
表是关系的关联表。该表中的外键指向表中的条目,User
因为它将用户链接到用户。
要将这个表添加到您的数据库中,您可以这样做:
ratings = db.Table('ratings'
db.Column('my_ratings_id', db.Integer, db.ForeignKey('user.id'))
db.Column('other_people_rating_id', db.Integet, db.ForeignKey('user.id'))
)
这是一个辅助表(如上所示直接翻译),除了外键之外没有其他数据。因此,它是在没有关联模型类的情况下创建的。
要在表中声明多对多关系User
,请添加以下内容:
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(32), unique=True, nullable=False)
def __repr__(self):
return f'{self.username}'
my_ratings = db.relationship(
'User',
secondary=ratings,
primaryjoin=(ratings.c.my_ratings_id == id),
secondaryjoin=(ratings.c.other_people_rating_id == id),
backref = db.backref('other_people_rating', lazy='dynamic'), lazy='dynamic'
)
我正在使用名称定义从左侧用户看到的关系,my_ratings
因为当您从左侧查询此关系时,您将获得右侧所有这些关系的列表。从视觉上看,这就是我的意思:
检查db.relationship()
调用的所有参数,您将看到:
User
是关系的右侧实体。secondary
配置ratings
关联表primaryjoin
表示将左侧实体与关联表链接的条件。应该user id
匹配my_ratings_id
secondaryjoin
表示将右侧实体与关联表链接的条件。再次,other_people_rating_id
应该匹配user
idbackref
定义如何从右侧实体访问此关系。从左侧开始,关系命名为my_ratings
,所以从右侧开始,我决定将其命名other_people_rating
为代表与右侧目标用户链接的所有左侧用户。- 该
dynamic
模式用于将查询设置为在特别请求之前不运行。 - 第二个
lazy
参数适用于左侧查询而不是右侧。
推荐阅读
- python - 如何从二值图像中去除不必要的黑度(主要由暗区/噪声引起)
- sapui5 - SAPUI5 UploadCollection - 项目的哪个模板?
- python - 在统计上下文中处理关联数据的正确方法
- google-chrome - 为在线购物网站设置相同站点 cookie
- reactjs - 响应未从服务器端显示
- angular - 如何用角度测试离子输入?
- c++ - 指针向量c ++中的映射函数
- python - Youtube Data API V3 返回 ssl.SSLWantWriteError: The operation did not complete (write) error 即使它之前工作过
- sql - 插入日期和时间时缺少逗号
- flutter - Flutter:在无状态小部件中,我得到“无法在初始化程序中访问实例成员 'xy'。” 在数组 xy 上使用长度时