Flask 多对多关系中 primaryjoin/secondaryjoin 的理解帮助
我有两个类,分别是用户(User)和列表(Listing),我想建立一个多对多的关系,这样一个用户可以有很多喜欢的列表,而任何一个列表也可以被很多用户喜欢。
我一直在参考这个链接,但这是我第一次处理多对多的关系,所以任何帮助都非常感谢。
出现了错误:InvalidRequestError:一个或多个映射器初始化失败 - 无法继续初始化其他映射器。原始异常是:无法确定主连接条件 'favorites_table.user_id = :user_id_1' 的关系方向,关系是 User.favorites。请确保引用的列对象有外键,或者是其父表上的外键约束的一部分,或者为这个关系指定 foreign_keys 参数。
models.py
favorites_table = db.Table('favorites_table',
db.Column('user_id', db.Integer, db.ForeignKey('listing.id')),
db.Column('listing_id', db.Integer, db.ForeignKey('user.id'))
)
class User(db.Model):
id = db.Column(db.Integer, primary_key = True)
listings = db.relationship('Listing', backref = 'manager', lazy = 'dynamic')
favorites = db.relationship('Listing',
secondary=favorites_table,
primaryjoin = ('favorites_table.c.user_id == id'),
secondaryjoin = ('favorites_table.c.listing_id == id'),
backref = db.backref('user', lazy = 'dynamic'),
lazy = 'dynamic')
def favorite_listing(self, listing):
if not self.is_favorite(listing):
self.favorites.append(listing)
return self
def unfavorite_listing(self, listing):
if self.is_favorite(listing):
self.favorites.remove(listing)
return self
def is_favorite(self, listing):
return self.favorites.filter(favorites_table.c.listing_id == listing.id).count() > 0
class Listing(db.Model):
id = db.Column(db.Integer, primary_key = True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
1 个回答
3
因为你的模型里已经指定了所有需要的 ForeignKey
(外键),所以sqlalchemy很聪明,能够自己搞定 primaryjoin
和 secondaryjoin
的参数。因此,这样写是完全可以的:
favorites = db.relationship('Listing',
secondary = favorites_table,
# primaryjoin = 'favorites_table.c.user_id == User.id',
# secondaryjoin = 'favorites_table.c.listing_id == Listing.id',
backref = db.backref('users', lazy = 'dynamic'),
lazy = 'dynamic',
)
如果你真的想要明确一点,可以把上面那两行注释去掉,结果是一样的。注意,我在每个 id
列前面加了模型名。
请注意,在你的 favorites_table
关系表中,列 user_id
指向的是 Listing.id
,而 listing_id
指向的是 User.id
,看起来应该是反过来的。