【问题标题】:Flask help understanding primaryjoin/secondaryjoin on a many-to-many relationshipFlask 帮助理解多对多关系上的primaryjoin/secondaryjoin
【发布时间】:2014-04-02 08:40:34
【问题描述】:

我有 User 和 Listing 类,我正在尝试创建多对多关系,以便用户可以拥有许多喜欢的列表,并且任何列表都可以被许多用户收藏。

我一直使用this 作为参考,但这是我的第一个多对多关系,因此我们将不胜感激。

InvalidRequestError:一个或多个映射器未能初始化 - 不能 继续初始化其他映射器。原来的例外是: 无法确定 primaryjoin 条件的关系方向 'favorites_table.user_id = :user_id_1',关于关系 用户的最爱。确保引用的 Column 对象具有 ForeignKey 存在,或者是 ForeignKeyConstraint 的一部分 他们的父表,或为此指定 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'))

【问题讨论】:

  • 为什么要将主/从连接条件指定为字符串?
  • 谢谢你,这是一个愚蠢的错误

标签: python sqlalchemy flask relationship


【解决方案1】:

由于您的模型已指定所有必需的 ForeignKeys,因此 sqlachemy 足够聪明,可以计算出 primaryjoinsecondaryjoin 本身的参数。所以这应该可以正常工作:

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,看起来应该是相反的。

【讨论】:

  • @van primaryjoin/secondaryjoin 到底是做什么的?
猜你喜欢
  • 2013-11-05
  • 2015-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 2014-04-08
  • 2021-01-24
相关资源
最近更新 更多