Подтвердить что ты не робот

Как "primaryjoin" и "secondaryjoin" работают для отношений "многие ко многим" в SQLAlchemy?

С трудом понимая некоторые вещи Flask-SQLAlchemy из Flask Mega Tutorial. Здесь код:

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() > 0

Итак, я понимаю, что, поскольку это взаимосвязь с саморефлексией, нам нужно каким-то образом для таблицы ассоциации выяснить, какой пользователь в таблице является последователем и какой пользователь в таблице является тем, за которым следует. Primaryjoin и secondaryjoin выполнить это, но как?

Три вещи, которые я не понимаю о Primaryjoin и secondaryjoin, следующие:

  • Какова цель Primaryjoin и secondaryjoin проверки равенства? Или, другими словами, как именно Primaryjoin и secondaryjoin добавляют user.id в таблицу ассоциаций?
  • Поскольку как Primaryjoin, так и secondaryjoin принимают требование user.id, которое user.id идет туда, где?
  • В моих методах follow/unfollow, как SQLAlchemy знает, что "я" является последователем и что пользователь прошел через тот, за которым следует?

Эти вопросы удержали меня от перехода к следующей главе, поэтому любые ответы очень ценятся.

4b9b3361

Ответ 1

  • В отношениях между многими и многими, выражение primaryjoin описывает соединение между левой таблицей и таблицей соединений, а secondaryjoin описывает соединение между таблицей соединений и правой таблицей. Другими словами, выражение primaryjoin говорит: "найти все строки в таблице последователей, где follower_id - X", выражение secondaryjoin говорит "найти все строки в таблице последователей, где follow_id is X", и собрать эти два вместе, чтобы найти все пользователи, которые следуют за пользователем X, и все пользователи, за которыми следует пользователь X.

  • Это зависит от направления, от которого вы запрашиваете. Когда вы попросите пользователя. После этого он найдет их, используя primaryjoin для запроса таблицы подписчиков для всех строк, где follow_id == user.id, и извлечения другого пользователя с помощью other.id == follower_id. Когда вы запрашиваете пользователя. После этого он использует secondaryjoin для запроса таблицы подписчиков для всех строк, где follower_id == user.id, и извлечения другого пользователя с помощью other.id == follow_id.

  • Потому что вы добавляете его в самостоятельную коллекцию. Говоря SQLAlchemy, кто-то сам следит. Если бы вы добавляли его в коллекцию self.followers, вы делали бы обратный, говоря SQLAlchemy, что "пользователь" является приверженцем себя.

Ссылка: Документация SQLAlchemy для указания альтернативных условий соединения (primaryjoin и secondaryjoin).