Python 当按关系名称访问时,Flask SqlAlchemy多对多关系仅返回一个结果

Python 当按关系名称访问时,Flask SqlAlchemy多对多关系仅返回一个结果,python,flask,sqlalchemy,many-to-many,Python,Flask,Sqlalchemy,Many To Many,我使用sql炼金术建立了一个简单的多对多关系,如下所示: file_favorites = db.Table('file_favorites', db.Column('file_id', db.Integer(), db.ForeignKey('file.id')), db.Column('user_id', db.Integer(), db.ForeignKey('user.

我使用sql炼金术建立了一个简单的多对多关系,如下所示:

file_favorites = db.Table('file_favorites',
                              db.Column('file_id', db.Integer(), db.ForeignKey('file.id')),
                              db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
                              db.Column('created_at', db.DateTime(), default=db.func.now()))


    class File(db.Model, helpers.ModelMixin):
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        name = db.Column(db.Unicode, nullable=False)
        description = db.Column(db.Unicode, nullable=False)
        created_at = db.Column(db.DateTime(), default=func.now())
        last_updated = db.Column(db.DateTime(), default=func.now(), onupdate=func.now())

        user_id = db.Column('user_id', db.Integer(), db.ForeignKey('user.id'), nullable=False, index=True)
        user = db.relationship('User')

        favorited_by = db.relationship('User', secondary=file_favorites, lazy='dynamic')   

        def is_favorite_of(self, user):
            query = File.query
            query = query.join(file_favorites)
            query = query.filter(file_favorites.c.file_id == self.id)
            query = query.filter(file_favorites.c.user_id == user.id)
            return query.count() > 0

        def favorite(self, user):
            if not self.is_favorite_of(user):
                self.favorited_by.append(user)

        def unfavorite(self, user):
            if self.is_favorite_of(user):
                self.favorited_by.remove(user)
我希望访问favorited_by属性将导致一个查询,该查询将尝试返回一个支持此文件的用户列表。但是,查询似乎只是访问第一个喜欢此文件的用户。我对此感到困惑,并希望我不能正确理解sqlalchemy的关系。以下是我正在经历的结果:

def create_model(model_class, *args, **kwargs):
    model = model_class(*args, **kwargs)
    db.session.add(model)
    db.session.commit()
    return model    

def test_favorited_by(self):
        user = create_model(User, username='user', email='user@user.net', password='password')
        user1 = create_model(User, username='user1', email='user1@user.net', password='password')
        user2 = create_model(User, username='user2', email='user2@user.net', password='password')


        file = create_model(File, name='file', description='a description', user=user)

        file.favorite(user1)
        file.favorite(user)
        file.favorite(user2)
        db.session.commit()
        print file.favorited_by
此查询中的结果:

SELECT "user".id AS user_id, "user".email AS user_email, "user".username AS user_username, "user".password AS user_password, "user".active AS user_active, "user".last_login_at AS user_last_login_at, "user".current_login_at AS user_current_login_at, "user".last_login_ip AS user_last_login_ip, "user".current_login_ip AS user_current_login_ip, "user".login_count AS user_login_count, "user".last_updated AS user_last_updated, "user".created_at AS user_created_at 
FROM "user", file_favorites 
WHERE :param_1 = file_favorites.file_id AND "user".id = file_favorites.user_id

最终返回user1,如果切换顺序,则第一个访问文件的用户将始终是返回的用户

你的问题在于
的最爱。它不会将
用户
合并到支票中。您需要添加另一个过滤器

def is_favorite_of(self, user):
    query = File.query
    query = query.join(file_favorites)
    query = query.filter(file_favorites.c.file_id == self.id)
    query = query.filter(file_favorites.c.user_id == user.id)
    return query.count() > 0
或者,整个功能可以简化为:

def is_favorite_of(self, user):
    return user in self.favorited_by

如果打印
file.favorited\u by.all()
,会发生什么情况?打印file.favorited\u by.all()返回:[]列表中的单个用户对象,该对象与user1(收藏夹的第一个用户)匹配。
file.favorite
看起来像什么?我猜它是在做类似于
self.favorited\u by=user
的事情,而不是
self.favorited\u by.append(user)
。为了清晰起见,我在代码中添加了最喜欢、最不喜欢和最喜欢的方法。我使用的是append,而不是equals。Using is_favorite_of(user)返回true,这似乎关系表被正确填充感谢您的回答,我也喜欢您的简化!有趣的是,这条线本来就在那里,我想我是用热键无意中把它删除了。