SQALCHEMY — фильтрация запросов по атрибуту и идентификатору пользователя

#flask-sqlalchemy

#flask-sqlalchemy

Вопрос:

У меня есть User модель и Playlist модель, которая ссылается user_id как foreign key

models.py

 class User(db.Model):

    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    playlists = db.relationship("Playlist",
                    backref=db.backref('user'), 
                    uselist=True)       

    def serialize(self):
       """Return object data in easily serializeable format"""
       return { 
        'id': self.id,
        'playlists' : self.playlists}


class Playlist(db.Model):
    """
    Model for storing playlist information belonging to a specific user
    """
    __tablename__ = 'playlist'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(50))    
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))

    @property
    def serialize(self):
       """Return object data in easily serializeable format"""
       return {
           'id' : self.id,
           'created' : self.created,
           'title': self.title,
       }
 

methods.py

 def Upload_Tracks(dataset):    
    try:
        playlist = Playlist.query.filter(Playlist.title == 'Cache').first()
        if not playlist:
            # create one
            playlist = Playlist(title='Cache', 
                                user=User.query.get(1))
            db.session.add(playlist)
            db.session.commit()
            db.session.commit()
        else:
            playlist = Playlist.query.filter(
                and_(Playlist.title == 'Cache', User.id == 1)).first()    
    # handler errors
    except (exc.IntegrityError, ValueError):
        db.session.rollback()

    return {"status": True}
 

На первой итерации создается список воспроизведения ADDED NEW <Playlist 'Cache'> , но на второй итерации, когда код достигает else , я получаю AttributeError: 'NoneType' object список воспроизведения здесь:

 playlist = Playlist.query.filter(
                    and_(Playlist.title == 'Cache', User.id == 1)).first() 
 

Если я запрашиваю фильтрацию только одного атрибута, например:

 playlist = Playlist.query.filter(
                (Playlist.title == 'Cache')).first()
 

это работает.

Итак, как мне запросить список воспроизведения по названию И идентификатору пользователя одновременно?

Ответ №1:

Вы получаете указанную выше ошибку, потому что пытались вызвать User.id атрибут, но вы не объединили эту модель (таблицу) с моделью списка воспроизведения (таблицей). В SQL есть соединения для объединения двух таблиц (LEFT, RIGHT, INNERJOIN …). SQLAlchemy, которую вы используете, обрабатывает этот необработанный SQL с помощью метода join . Поэтому вам нужно использовать метод join() для объединения двух таблиц (моделей).

 playlist = Playlist.query.join(User, User.id == Playlist.user_id).filter(
                    and_(Playlist.title == 'Cache', User.id == 1)).first()
 

Вы получите список воспроизведения как None (если в БД нет такой строки) или Object, если есть такая строка.