SQLAlchemy: retrieve all episodes from favorite_series of specific user SQLAlchemy: retrieve all episodes from favorite_series of specific user flask flask

SQLAlchemy: retrieve all episodes from favorite_series of specific user


First of all you don't seem to be declaring your table names? Also, the whole point of bothering with orm is so you never have to write sql queries:

from sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import ormimport sqlalchemy as dbBase = declarative_base()favorite_series = db.Table('favorite_series', Base.metadata,    db.Column('user_id', db.Integer, db.ForeignKey('User.id')),    db.Column('series_id', db.Integer, db.ForeignKey('Series.id')))class Episode(Base):    __tablename__ = 'Episode'    id = db.Column(db.Integer, primary_key=True)    season = db.Column(db.Integer)    episode_num = db.Column(db.Integer)    series_id = db.Column(db.Integer, db.ForeignKey('Series.id'))    def __init__(self, season, episode_num, series_id):        self.season = season        self.episode_num = episode_num        self.series_id = series_id    def __repr__(self):        return self.series.title + \               ' S' + str(self.season) + \               'E' + str(self.episode_num)class Series(Base):    __tablename__ = 'Series'    id = db.Column(db.Integer, primary_key=True)    title = db.Column(db.String)    episodes = orm.relationship('Episode', backref='series')    def __init__(self, title):        self.title = title    def __repr__(self):        return self.titleclass User(Base):    __tablename__ = 'User'    id = db.Column(db.Integer, primary_key=True)    name = db.Column(db.String)    favorite_series = orm.relationship('Series',         secondary=favorite_series, backref='users')    def __init__(self, name):        self.name = name    def __repr__(self):        return self.name

Now you can just access the attributes of your objects and let sql alchemy deal with keeping you DB in sync and issuing queries.

engine = db.create_engine('sqlite:///:memory:')session = orm.sessionmaker(bind=engine)()Base.metadata.create_all(engine)lt = User('Ludovic Tiako')the_wire = Series('The Wire')friends = Series('Friends')session.add_all([lt, the_wire, friends])session.commit() # need to commit here to generate the id fieldstw_s01e01 = Episode(1,1,the_wire.id)tw_s01e02 = Episode(1,2,the_wire.id)f_s01e01 = Episode(1,1,friends.id)f_s01e02 = Episode(1,2,friends.id)f_s01e03 = Episode(1,3,friends.id)session.add_all([tw_s01e01, tw_s01e02,                 f_s01e01, f_s01e02, f_s01e03])session.commit()the_wire.episodes # > [The Wire S1E1, The Wire S1E2]friends.episodes # > [Friends S1E1, Friends S1E2, Friends S1E3]

Finally, to answer your question:

lt.favorite_series.append(the_wire)session.commit()lt.favorite_series # > [The Wire][s.episodes for s in lt.favorite_series] # >> [[The Wire S1E1, The Wire S1E2]]


I don't know about Flask, but from the docs of Flask-SQLAlchemy, it seems it uses declarative, so the ORM. And so, you should have a session. I think it is accessible to you from db.session.

Anyway, if those assumptions are true, this is how you should do it:

query = db.session.query(User.id, Series.name, Episode.name).filter((Episode.series_id == Series.id) & \    (User.id == favorite_series.c.user_id) & (Series.id == favorite_series.c.id) & \    (User.id == 1))results = query.all();

It might not be the exact query you provided, but should do the same.

UPDATE: I just checked Flask-SQLALchemy code on github, it seems that db is an instance of SQLAlchemy, which has a session attribute, created by self.session = self.create_scoped_session(session_options) which returns a session object. So this should work.

Also, not that by doing that, you won't be using their BaseQuery, although I don't know what that would mean...

Check the documentation to know what to do exactly.