title: How do 'primaryjoin' and 'secondaryjoin' work for many-to-many relationship in SQLAlchemy?
body: <p>Having some difficulty understanding some Flask-SQLAlchemy stuff from the <a href="http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-viii-followers-contacts-and-friends" rel="noreferrer">Flask Mega Tutorial</a>. Here's the code:</p>
  
  <pre><code>followers = db.Table('followers',
      db.Column('follower_id', db.Integer, db.ForeignKey('user.id')),
      db.Column('followed_id', db.Integer, db.ForeignKey('user.id'))
  )
  
  class User(db.Model):
      id = db.Column(db.Integer, primary_key = True)
      nickname = db.Column(db.String(64), unique = True)
      email = db.Column(db.String(120), index = True, unique = True)
      role = db.Column(db.SmallInteger, default = ROLE_USER)
      posts = db.relationship('Post', backref = 'author', lazy = 'dynamic')
      about_me = db.Column(db.String(140))
      last_seen = db.Column(db.DateTime)
      followed = db.relationship('User', 
          secondary = followers, 
          primaryjoin = (followers.c.follower_id == id), 
          secondaryjoin = (followers.c.followed_id == id), 
          backref = db.backref('followers', lazy = 'dynamic'), 
          lazy = 'dynamic')
  
      def follow(self, user):
          if not self.is_following(user):
              self.followed.append(user)
              return self
  
      def unfollow(self, user):
          if self.is_following(user):
              self.followed.remove(user)
              return self
  
      def is_following(self, user):
          return self.followed.filter(followers.c.followed_id == user.id).count() &gt; 0
  </code></pre>
  
  <p>So I understand that because this is a self-referential relationship, we need some way for the association table to figure out which User in the table is the follower and which User in the table is the one being followed. <code>Primaryjoin</code> and <code>secondaryjoin</code> accomplish this, but how? </p>
  
  <p>Three things I don't understand about <code>primaryjoin</code> and <code>secondaryjoin</code> are as follows:</p>
  
  <ol>
  <li>What's the purpose of <code>primaryjoin</code> and <code>secondaryjoin</code> checking equality? Or, in other words, how exactly does <code>primaryjoin</code> and <code>secondaryjoin</code> add <code>user.id</code>s to the association table?</li>
  <li>Since both <code>primaryjoin</code> and <code>secondaryjoin</code> take a <code>user.id</code> requirement, which <code>user.id</code> goes where?</li>
  <li>In my follow/unfollow methods, how does SQLAlchemy know that self is the follower and that the user passed in is the one being followed?</li>
  </ol>
  
  <p>These questions have been holding me back from moving on to the next chapter, so any answers are very appreciated.</p>